Compare commits
36 Commits
f006ca5a2b
...
b662da584a
Author | SHA1 | Date | |
---|---|---|---|
b662da584a | |||
311623e208 | |||
fadbb6a911 | |||
0afefe44ca | |||
71ec027000 | |||
c913be2690 | |||
217cf85ea4 | |||
d5cf2a600e | |||
e6f235036e | |||
35a7825759 | |||
4bd192dc87 | |||
78de3276d3 | |||
cabf64088b | |||
a50fbc26d7 | |||
d92a540786 | |||
db6d39e02e | |||
d01a56d9dc | |||
16eb852d9d | |||
460472b29a | |||
3579ff100f | |||
731c423483 | |||
c3a2e68980 | |||
84246a3a61 | |||
23ceb718e9 | |||
9cb43687c4 | |||
fe9c299d64 | |||
16fda90d96 | |||
f6afa97b2d | |||
7be3859988 | |||
f1339ad082 | |||
ac812246ea | |||
177da7a28a | |||
e520f3b581 | |||
7e7d21f9ce | |||
dc35cb8354 | |||
a517e694aa |
@ -5,7 +5,7 @@ VITE_APP_TITLE = 煤科建管平台
|
||||
VITE_APP_ENV = 'development'
|
||||
|
||||
# 开发环境
|
||||
VITE_APP_BASE_API = 'http://192.168.110.149:8899'
|
||||
VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||
# VITE_APP_BASE_API = 'http://58.17.134.85:8899'
|
||||
# GO开发环境
|
||||
VITE_APP_BASE_API_GO = 'http://xny.yj-3d.com:7464'
|
||||
|
1
public/vite.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/xx.xlsx
Normal file
@ -16,6 +16,17 @@ export const listContactnotice = (query?: ContactnoticeQuery): AxiosPromise<Cont
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据项目id查询项目班组班组长信息列表
|
||||
* @param projectId
|
||||
*/
|
||||
export const listProjectTeamForeman = (projectId: string | number): AxiosPromise<any[]> => {
|
||||
return request({
|
||||
url: '/project/projectTeam/listForeman/' + projectId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询联系单详细
|
||||
* @param id
|
||||
|
13
src/api/enterpriseLarge/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
/**
|
||||
* 查询企业关键指标
|
||||
*/
|
||||
|
||||
export const keyIndex = () => {
|
||||
return request({
|
||||
url: '/enterprise/big/screen/keyIndex',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
import request from '@/utils/request-go';
|
||||
import request1 from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import {
|
||||
QualityVO,
|
||||
@ -172,7 +173,7 @@ export const getweatherList = (): AxiosPromise<weatherVO[]> => {
|
||||
*/
|
||||
|
||||
export const getSafetyDay = (id?: string): AxiosPromise<safetyDayVO> => {
|
||||
return request({
|
||||
return request1({
|
||||
url: '/project/project/safetyDay/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
|
@ -98,3 +98,18 @@ export const cashTotal = () => {
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
//安全天数
|
||||
export const getSafetyDay = (projectId) => {
|
||||
return request({
|
||||
url: '/money/big/screen/safetyDay/' + projectId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
//安全天数
|
||||
export const getWeather = (projectId) => {
|
||||
return request({
|
||||
url: '/money/big/screen/weather/' + projectId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
@ -1,63 +1,45 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { MachineryForm, MachineryQuery, MachineryVO } from '@/api/machinery/machinery/types';
|
||||
|
||||
/**
|
||||
* 查询机械列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listMachinery = (query?: MachineryQuery): AxiosPromise<MachineryVO[]> => {
|
||||
import request from '@/utils/request-go';
|
||||
// 查询机械列表
|
||||
export function listBusMachinery(query: object) {
|
||||
return request({
|
||||
url: '/machinery/machinery/list',
|
||||
url: '/zm/api/v1/system/busMachinery/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询机械详细
|
||||
* @param id
|
||||
*/
|
||||
export const getMachinery = (id: string | number): AxiosPromise<MachineryVO> => {
|
||||
}
|
||||
// 查询机械详细
|
||||
export function getBusMachinery(id: number) {
|
||||
return request({
|
||||
url: '/machinery/machinery/' + id,
|
||||
method: 'get'
|
||||
url: '/zm/api/v1/system/busMachinery/get',
|
||||
method: 'get',
|
||||
params: {
|
||||
id: id.toString()
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增机械
|
||||
* @param data
|
||||
*/
|
||||
export const addMachinery = (data: MachineryForm): AxiosPromise<string | number> => {
|
||||
}
|
||||
// 新增机械
|
||||
export function addBusMachinery(data: object) {
|
||||
return request({
|
||||
url: '/machinery/machinery',
|
||||
url: '/zm/api/v1/system/busMachinery/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改机械
|
||||
* @param data
|
||||
*/
|
||||
export const updateMachinery = (data: MachineryForm) => {
|
||||
}
|
||||
// 修改机械
|
||||
export function updateBusMachinery(data: object) {
|
||||
return request({
|
||||
url: '/machinery/machinery',
|
||||
url: '/zm/api/v1/system/busMachinery/edit',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除机械
|
||||
* @param id
|
||||
*/
|
||||
export const delMachinery = (id: string | number | Array<string | number>) => {
|
||||
}
|
||||
// 删除机械
|
||||
export function delBusMachinery(ids: number[]) {
|
||||
return request({
|
||||
url: '/machinery/machinery/' + id,
|
||||
method: 'delete'
|
||||
url: '/zm/api/v1/system/busMachinery/delete',
|
||||
method: 'delete',
|
||||
data: {
|
||||
ids: ids
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -1,63 +1,45 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { MachineryDetailForm, MachineryDetailQuery, MachineryDetailVO } from '@/api/machinery/machineryDetail/types';
|
||||
|
||||
/**
|
||||
* 查询机械详情列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listMachineryDetail = (query?: MachineryDetailQuery): AxiosPromise<MachineryDetailVO[]> => {
|
||||
import request from '@/utils/request-go';
|
||||
// 查询机械详情列表
|
||||
export function listBusMachineryDetail(query: object) {
|
||||
return request({
|
||||
url: '/machinery/machineryDetail/list',
|
||||
url: '/zm/api/v1/system/busMachineryDetail/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询机械详情详细
|
||||
* @param id
|
||||
*/
|
||||
export const getMachineryDetail = (id: string | number): AxiosPromise<MachineryDetailVO> => {
|
||||
}
|
||||
// 查询机械详情详细
|
||||
export function getBusMachineryDetail(id: number) {
|
||||
return request({
|
||||
url: '/machinery/machineryDetail/' + id,
|
||||
method: 'get'
|
||||
url: '/zm/api/v1/system/busMachineryDetail/get',
|
||||
method: 'get',
|
||||
params: {
|
||||
id: id.toString()
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增机械详情
|
||||
* @param data
|
||||
*/
|
||||
export const addMachineryDetail = (data: MachineryDetailForm): AxiosPromise<string | number> => {
|
||||
}
|
||||
// 新增机械详情
|
||||
export function addBusMachineryDetail(data: object) {
|
||||
return request({
|
||||
url: '/machinery/machineryDetail',
|
||||
url: '/zm/api/v1/system/busMachineryDetail/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改机械详情
|
||||
* @param data
|
||||
*/
|
||||
export const updateMachineryDetail = (data: MachineryDetailForm) => {
|
||||
}
|
||||
// 修改机械详情
|
||||
export function updateBusMachineryDetail(data: object) {
|
||||
return request({
|
||||
url: '/machinery/machineryDetail',
|
||||
url: '/zm/api/v1/system/busMachineryDetail/edit',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除机械详情
|
||||
* @param id
|
||||
*/
|
||||
export const delMachineryDetail = (id: string | number | Array<string | number>) => {
|
||||
}
|
||||
// 删除机械详情
|
||||
export function delBusMachineryDetail(ids: number[]) {
|
||||
return request({
|
||||
url: '/machinery/machineryDetail/' + id,
|
||||
method: 'delete'
|
||||
url: '/zm/api/v1/system/busMachineryDetail/delete',
|
||||
method: 'delete',
|
||||
data: {
|
||||
ids: ids
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import request from '@/utils/request-go';
|
||||
import requestGo from '@/utils/request-go';
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { CompanyForm, CompanyQuery, CompanyVO } from '@/api/materials/company/types';
|
||||
|
||||
@ -9,7 +10,7 @@ import { CompanyForm, CompanyQuery, CompanyVO } from '@/api/materials/company/ty
|
||||
*/
|
||||
|
||||
export const listCompany = (query?: CompanyQuery): AxiosPromise<CompanyVO[]> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busCompany/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
|
@ -1,4 +1,5 @@
|
||||
import request from '@/utils/request-go';
|
||||
import requestGo from '@/utils/request-go';
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { MaterialsForm, MaterialsQuery, MaterialsVO } from '@/api/materials/materials/types';
|
||||
|
||||
@ -8,7 +9,7 @@ import { MaterialsForm, MaterialsQuery, MaterialsVO } from '@/api/materials/mate
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listMaterials = (query?: MaterialsQuery): AxiosPromise<MaterialsVO[]> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busEquipmentMaterials/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
@ -20,7 +21,7 @@ export const listMaterials = (query?: MaterialsQuery): AxiosPromise<MaterialsVO[
|
||||
* @param id
|
||||
*/
|
||||
export const getMaterials = (id: string | number): AxiosPromise<MaterialsVO> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busEquipmentMaterials/get',
|
||||
method: 'get',
|
||||
params: {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import request from '@/utils/request-go';
|
||||
import requestGo from '@/utils/request-go';
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { MaterialsInventoryForm, MaterialsInventoryQuery, MaterialsInventoryVO } from '@/api/materials/materialsInventory/types';
|
||||
|
||||
@ -9,7 +10,7 @@ import { MaterialsInventoryForm, MaterialsInventoryQuery, MaterialsInventoryVO }
|
||||
*/
|
||||
|
||||
export const listMaterialsInventory = (query?: MaterialsInventoryQuery): AxiosPromise<MaterialsInventoryVO[]> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busEquipmentMaterialsInventory/excellist',
|
||||
method: 'get',
|
||||
params: query
|
||||
|
43
src/api/outputApi/index.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
/**
|
||||
* 查询项目数据
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const projectProgress = (query?: any): any => {
|
||||
return request({
|
||||
url: '/enterprise/big/screen/projectProgress',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 产值
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const outpuProgress = (query?: any): any => {
|
||||
return request({
|
||||
url: '/enterprise/big/screen/projectOutputValueComparison',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 预警
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const earlyWarning = (query?: any): any => {
|
||||
return request({
|
||||
url: '/enterprise/big/screen/riskEarlyWarning',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
import request from '@/utils/request-go';
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import {
|
||||
ConstructionUserForm,
|
||||
@ -23,7 +23,7 @@ import requestGo from '@/utils/request-go';
|
||||
*/
|
||||
|
||||
export const listConstructionMonth = (query?: ConstructionMonthQuery): AxiosPromise<AttendanceMonthVO[]> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/wxApplet/wxApplet/busAttendance/byOpenId',
|
||||
method: 'get',
|
||||
params: query
|
||||
@ -62,7 +62,7 @@ export const listConstructionUserInTeam = (query?: ConstructionUserQuery): Axios
|
||||
* @param id
|
||||
*/
|
||||
export const getConstructionUser = (id: string | number): AxiosPromise<ConstructionUserVO> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/wxApplet/wxApplet/busConstructionUser/getDetails?id=' + id,
|
||||
method: 'get'
|
||||
});
|
||||
@ -73,7 +73,7 @@ export const getConstructionUser = (id: string | number): AxiosPromise<Construct
|
||||
* @param data
|
||||
*/
|
||||
export const transferConstructionUser = (data: skipType) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/wxApplet/wxApplet/busConstructionUser/changePay',
|
||||
method: 'put',
|
||||
data: data
|
||||
@ -84,7 +84,7 @@ export const transferConstructionUser = (data: skipType) => {
|
||||
* 查询项目以及项目下的分包公司列表
|
||||
*/
|
||||
export const getProjectContractorList = () => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/sysProject/list?pageNum=1&pageSize=1000',
|
||||
method: 'get'
|
||||
});
|
||||
@ -95,7 +95,7 @@ export const getProjectContractorList = () => {
|
||||
* @param data
|
||||
*/
|
||||
export const addConstructionUser = (data: ConstructionUserForm): AxiosPromise<string | number> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/wxApplet/wxApplet/busConstructionUser/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
@ -107,7 +107,7 @@ export const addConstructionUser = (data: ConstructionUserForm): AxiosPromise<st
|
||||
* @param data
|
||||
*/
|
||||
export const updateConstructionUser = (data: ConstructionUserForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionUser/pcEdit',
|
||||
method: 'put',
|
||||
data: data
|
||||
@ -119,7 +119,7 @@ export const updateConstructionUser = (data: ConstructionUserForm) => {
|
||||
* @param id
|
||||
*/
|
||||
export const delConstructionUser = (data) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/wxApplet/wxApplet/busConstructionUser/delete',
|
||||
method: 'delete',
|
||||
data
|
||||
@ -131,7 +131,7 @@ export const delConstructionUser = (data) => {
|
||||
* @param data
|
||||
*/
|
||||
export const updateConstructionUserStatus = (data: ConstructionUserStatusForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/wxApplet/wxApplet/busConstructionUser/changeState',
|
||||
method: 'delete',
|
||||
data: data
|
||||
@ -143,7 +143,7 @@ export const updateConstructionUserStatus = (data: ConstructionUserStatusForm) =
|
||||
* @param data
|
||||
*/
|
||||
export const updateConstructionUserPlayCardStatus = (data: ConstructionUserPlayCardForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionUser/oneClickOpen',
|
||||
method: 'put',
|
||||
data: data
|
||||
@ -155,7 +155,7 @@ export const updateConstructionUserPlayCardStatus = (data: ConstructionUserPlayC
|
||||
* @param data
|
||||
*/
|
||||
export const updateConstructionUserPlayCardOneStatus = (data: ConstructionUserPlayCardForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionUser/clockingCondition',
|
||||
method: 'put',
|
||||
data: data
|
||||
@ -167,7 +167,7 @@ export const updateConstructionUserPlayCardOneStatus = (data: ConstructionUserPl
|
||||
* @param data
|
||||
*/
|
||||
export const updateConstructionUserSalary = (data: ConstructionUserSalaryForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/wxApplet/wxApplet/busConstructionUser/payEdit',
|
||||
method: 'put',
|
||||
data: data
|
||||
@ -179,7 +179,7 @@ export const updateConstructionUserSalary = (data: ConstructionUserSalaryForm) =
|
||||
* @param query
|
||||
*/
|
||||
export const getConstructionUserExit = (query: ConstructionUserExitForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionUser/departureRecord',
|
||||
method: 'post',
|
||||
data: query
|
||||
@ -191,7 +191,7 @@ export const getConstructionUserExit = (query: ConstructionUserExitForm) => {
|
||||
* @param query
|
||||
*/
|
||||
export const dowloadConstructionUserTemplate = (query: ConstructionUserTemplateForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionUser/templateExport',
|
||||
method: 'get',
|
||||
params: query
|
||||
@ -208,7 +208,7 @@ export const dowloadConstructionUserTemplate = (query: ConstructionUserTemplateF
|
||||
* @param data
|
||||
*/
|
||||
export const delConstructionUserMember = (data: ConstructionUserMembeForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionUser/departure',
|
||||
method: 'post',
|
||||
data
|
||||
|
@ -64,3 +64,27 @@ export const getScreenGeneralize = (projectId: number | string) => {
|
||||
method: 'get',
|
||||
});
|
||||
};
|
||||
|
||||
// 获取gps数据
|
||||
export const getGps = (projectId) => {
|
||||
return request({
|
||||
url: '/project/big/screen/getClientList/' + projectId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
// 选中列表
|
||||
export const getSelectList = (params) => {
|
||||
return request({
|
||||
url: '/project/big/screen/getList',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
};
|
||||
// 设置选中
|
||||
export const setSelect = (data) => {
|
||||
return request({
|
||||
url: '/project/big/screen/setList',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
import request from '@/utils/request-go';
|
||||
import requestGo from '@/utils/request-go';
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { QualityConstructionLogVO, QualityConstructionLogForm, QualityConstructionLogQuery } from '@/api/quality/qualityConstructionLog/types';
|
||||
|
||||
@ -9,7 +10,7 @@ import { QualityConstructionLogVO, QualityConstructionLogForm, QualityConstructi
|
||||
*/
|
||||
|
||||
export const listQualityConstructionLog = (query?: QualityConstructionLogQuery): AxiosPromise<QualityConstructionLogVO[]> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionLog/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
@ -21,8 +22,8 @@ export const listQualityConstructionLog = (query?: QualityConstructionLogQuery):
|
||||
* @param id
|
||||
*/
|
||||
export const getQualityConstructionLog = (id: string | number): AxiosPromise<QualityConstructionLogVO> => {
|
||||
return request({
|
||||
url: 'zm/api/v1/system/busConstructionLog/get',
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionLog/get',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
@ -57,7 +58,7 @@ export const updateQualityConstructionLog = (data: QualityConstructionLogForm) =
|
||||
* @param id
|
||||
*/
|
||||
export const delQualityConstructionLog = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busConstructionLog/delete',
|
||||
method: 'delete',
|
||||
data: { ids: id }
|
||||
|
@ -1,4 +1,5 @@
|
||||
import request from '@/utils/request-go';
|
||||
import requestGo from '@/utils/request-go';
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { SafetyWeeklyReportForm, SafetyWeeklyReportQuery, SafetyWeeklyReportVO } from '@/api/safety/safetyWeeklyReport/types';
|
||||
|
||||
@ -9,7 +10,7 @@ import { SafetyWeeklyReportForm, SafetyWeeklyReportQuery, SafetyWeeklyReportVO }
|
||||
*/
|
||||
|
||||
export const listSafetyWeeklyReport = (query?: SafetyWeeklyReportQuery): AxiosPromise<SafetyWeeklyReportVO[]> => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busWeeklySecurityReport/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
@ -32,7 +33,7 @@ export const getSafetyWeeklyReport = (id: string | number): AxiosPromise<SafetyW
|
||||
* @param data
|
||||
*/
|
||||
export const addSafetyWeeklyReport = (data: SafetyWeeklyReportForm) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busWeeklySecurityReport/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
@ -56,7 +57,7 @@ export const updateSafetyWeeklyReport = (data: SafetyWeeklyReportForm) => {
|
||||
* @param id
|
||||
*/
|
||||
export const delSafetyWeeklyReport = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
return requestGo({
|
||||
url: '/zm/api/v1/system/busWeeklySecurityReport/delete',
|
||||
method: 'delete',
|
||||
data: { ids: id }
|
||||
|
@ -61,3 +61,22 @@ export const delSupplierInput = (id: string | number | Array<string | number>) =
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
//导入供商入库
|
||||
export const leadingIn = (formData: FormData, projectId) => {
|
||||
return request({
|
||||
url: '/supplierInput/supplierInput/import?projectId=' + projectId,
|
||||
method: 'post',
|
||||
data: formData,
|
||||
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
//导入供商出库
|
||||
export const leadingOut = () => {
|
||||
return request({
|
||||
url: '/supplierInput/supplierInput/export',
|
||||
method: 'post'
|
||||
});
|
||||
};
|
||||
|
@ -31,3 +31,20 @@ export function delOss(ossId: string | number | Array<string | number>) {
|
||||
export function downLoadOss(ossId: { id?: string | number; idList?: string | number | Array<string | number> }, url: string, fileName: string) {
|
||||
return download(url, ossId, fileName);
|
||||
}
|
||||
|
||||
//识别身份证
|
||||
export function recognizeidCard(data: any, type: any) {
|
||||
return request({
|
||||
url: '/contractor/constructionUser/idCard?idCardSide=' + type,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
//识别银行卡
|
||||
export function recognizeBankCard(data: any) {
|
||||
return request({
|
||||
url: '/contractor/constructionUser/bankCard',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
BIN
src/assets/images/beUnder.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
src/assets/images/break.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/images/constructor.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
src/assets/images/contract.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/assets/images/manager.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
src/assets/images/subcontractor.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
src/assets/images/todayConstruction.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
src/assets/images/totalCapacity.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/large/actual.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
src/assets/large/capacity.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
src/assets/large/delay.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
src/assets/large/plan.png
Normal file
After Width: | Height: | Size: 26 KiB |
@ -53,7 +53,7 @@
|
||||
style="margin-top: 10px"
|
||||
v-for="(file, index) in fileList"
|
||||
:key="file.uid"
|
||||
class="el-upload-list__item upload-list__item-content"
|
||||
class="el-upload-list__item ele-upload-list__item-content"
|
||||
v-if="autoUpload"
|
||||
>
|
||||
<el-link :href="`${file.url}`" :underline="false" target="_blank">
|
||||
@ -226,7 +226,12 @@ watch(
|
||||
);
|
||||
// 上传前校检格式和大小
|
||||
const handleBeforeUpload = (file: any) => {
|
||||
if (!validateFile(file)) return false;
|
||||
if (!validateFile(file)) {
|
||||
if (props.isGo) {
|
||||
fileList.value = [];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
proxy?.$modal.loading('正在上传文件,请稍候...');
|
||||
number.value++;
|
||||
return true;
|
||||
@ -266,7 +271,6 @@ interface UploadFileWithOssId extends UploadFile {
|
||||
}
|
||||
|
||||
const handleUploadSuccess = (res: any, file: UploadFileWithOssId) => {
|
||||
console.log('🚀 ~ handleUploadSuccess ~ res:', res.code);
|
||||
if (res.code === 200 || res.code === 0) {
|
||||
console.log('上传成功');
|
||||
// 上传成功,不管 data 是否为空
|
||||
@ -277,6 +281,9 @@ const handleUploadSuccess = (res: any, file: UploadFileWithOssId) => {
|
||||
});
|
||||
} else {
|
||||
console.log('失败', res);
|
||||
if (props.isGo) {
|
||||
fileList.value = [];
|
||||
}
|
||||
|
||||
number.value--;
|
||||
proxy?.$modal.closeLoading();
|
||||
@ -311,8 +318,6 @@ const handleChange = (file: any, filelist: any) => {
|
||||
|
||||
// 删除文件
|
||||
const handleRemove = (file: any, fileList: any) => {
|
||||
console.log(11);
|
||||
|
||||
emit('handleRemove', file, fileList);
|
||||
};
|
||||
|
||||
@ -330,12 +335,15 @@ const handleDelete = async (index: string | number, type?: string) => {
|
||||
delOss(index);
|
||||
fileList.value = fileList.value.filter((f) => f.ossId !== index);
|
||||
} else {
|
||||
if (!props.isGo) {
|
||||
let ossId = fileList.value[index].ossId;
|
||||
delOss(ossId);
|
||||
}
|
||||
index = parseInt(index as string);
|
||||
fileList.value.splice(index, 1);
|
||||
}
|
||||
} finally {
|
||||
// fileList.value = [];
|
||||
emit('handleRemove');
|
||||
emit('update:modelValue', listToString(fileList.value));
|
||||
}
|
||||
|
@ -41,7 +41,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { listByIds, delOss } from '@/api/system/oss';
|
||||
import { listByIds, delOss, recognizeidCard, recognizeBankCard } from '@/api/system/oss';
|
||||
import { OssVO } from '@/api/system/oss/types';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { globalHeaders } from '@/utils/request';
|
||||
@ -63,24 +63,37 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isGo: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 图片上传路径
|
||||
action: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 是否支持压缩,默认否
|
||||
compressSupport: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 压缩目标大小,单位KB。默认300KB以上文件才压缩,并压缩至300KB以内
|
||||
compressTargetSize: propTypes.number.def(300)
|
||||
compressTargetSize: propTypes.number.def(300),
|
||||
idCardType: {
|
||||
type: String,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const emit = defineEmits(['update:modelValue', 'success']);
|
||||
const number = ref(0);
|
||||
const uploadList = ref<any[]>([]);
|
||||
const dialogImageUrl = ref('');
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
const baseUrl = import.meta.env.VITE_APP_BASE_API;
|
||||
const uploadImgUrl = ref(baseUrl + '/resource/oss/upload'); // 上传的图片服务器地址
|
||||
const baseUrl = props.isGo ? import.meta.env.VITE_APP_BASE_API_GO : import.meta.env.VITE_APP_BASE_API;
|
||||
const uploadImgUrl = ref(baseUrl + props.action ? props.action : '/resource/oss/upload'); // 上传的图片服务器地址
|
||||
const headers = ref(globalHeaders());
|
||||
|
||||
const fileList = ref<any[]>([]);
|
||||
@ -121,7 +134,7 @@ watch(
|
||||
);
|
||||
|
||||
/** 上传前loading加载 */
|
||||
const handleBeforeUpload = (file: any) => {
|
||||
const handleBeforeUpload = async (file: any) => {
|
||||
let isImg = false;
|
||||
if (props.fileType.length) {
|
||||
let fileExtension = '';
|
||||
@ -169,10 +182,32 @@ const handleExceed = () => {
|
||||
};
|
||||
|
||||
// 上传成功回调
|
||||
const handleUploadSuccess = (res: any, file: UploadFile) => {
|
||||
const handleUploadSuccess = async (res: any, file: UploadFile) => {
|
||||
if (res.code === 200) {
|
||||
uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
|
||||
uploadedSuccessfully();
|
||||
if (props.idCardType) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file.raw); // 假设后端接收的字段名为file
|
||||
if (props.idCardType === 'front' || props.idCardType === 'back') {
|
||||
const res = await recognizeidCard(formData, props.idCardType);
|
||||
if (res.code === 200) {
|
||||
proxy?.$modal.msgSuccess('身份证识别成功');
|
||||
emit('success', res.data);
|
||||
} else {
|
||||
proxy?.$modal.msgError('身份证识别失败');
|
||||
}
|
||||
}
|
||||
if (props.idCardType === 'bank') {
|
||||
const res = await recognizeBankCard(formData);
|
||||
if (res.code === 200) {
|
||||
proxy?.$modal.msgSuccess('银行卡识别成功');
|
||||
emit('success', res.data);
|
||||
} else {
|
||||
proxy?.$modal.msgError('银行卡识别失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
number.value--;
|
||||
proxy?.$modal.closeLoading();
|
||||
@ -201,8 +236,7 @@ const uploadedSuccessfully = () => {
|
||||
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
|
||||
uploadList.value = [];
|
||||
number.value = 0;
|
||||
console.log(fileList.value);
|
||||
|
||||
console.log(listToString(fileList.value));
|
||||
emit('update:modelValue', listToString(fileList.value));
|
||||
proxy?.$modal.closeLoading();
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ const instance = axios.create({
|
||||
});
|
||||
import sign from '@/utils/sign.js';
|
||||
import { getGoToken } from '@/utils/auth';
|
||||
const BASE_URL = 'http://58.17.134.85:8919';
|
||||
const BASE_URL = 'http://58.17.134.85:8920';
|
||||
const acceptConfig = ['.zip', '.rar']; //文件
|
||||
// const acceptConfig = {
|
||||
// // image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'],
|
||||
|
244
src/components/uploadImg/index.vue
Normal file
@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<div class="up-img" v-if="limit > 1">
|
||||
<el-upload
|
||||
v-model:file-list="dataFileList"
|
||||
:limit="limit"
|
||||
:action="action"
|
||||
:multiple="multiple"
|
||||
:list-type="listType"
|
||||
:on-success="handleAvatarSuccess"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="handleExceed"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
:data="dataParam"
|
||||
:name="fileName"
|
||||
:headers="headers"
|
||||
ref="elUploadRef"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<img w-full :src="dialogImageUrl" alt="Preview Image" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="up-img">
|
||||
<el-upload
|
||||
ref="elUploadRef"
|
||||
v-model:file-list="dataFileList"
|
||||
:limit="limit"
|
||||
class="avatar-uploader"
|
||||
:action="action"
|
||||
:show-file-list="false"
|
||||
:on-success="handleAvatarSuccess"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="handleRemove"
|
||||
:on-exceed="handleExceed"
|
||||
:data="dataParam"
|
||||
:name="fileName"
|
||||
:headers="headers"
|
||||
>
|
||||
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
|
||||
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed, getCurrentInstance, reactive, toRefs } from 'vue';
|
||||
import type { UploadProps, UploadUserFile, UploadInstance } from 'element-plus';
|
||||
import { ElMessage, genFileId } from 'element-plus';
|
||||
import _ from 'lodash';
|
||||
import sign from '@/utils/sign.js';
|
||||
export default defineComponent({
|
||||
name: 'uploadImg',
|
||||
props: {
|
||||
action: { type: String, default: '' }, //上传地址
|
||||
name: { type: String, default: 'file' }, //上传文件类型
|
||||
limit: { type: Number, default: 1 }, //上传最大数量
|
||||
method: { type: String, default: 'post' }, //设置上传请求方法
|
||||
multiple: { type: Boolean, default: true }, //是否支持多选文件
|
||||
showFileList: { type: Boolean, default: true }, //是否显示已上传文件列表
|
||||
drag: { type: Boolean, default: false }, //是否启用拖拽上传
|
||||
accept: { type: String, default: '' }, //接受上传的文件类型格式
|
||||
disabled: { type: Boolean, default: false }, //是否是否禁止上传
|
||||
listType: { type: String, default: 'picture-card' }, //是否启用拖拽上传
|
||||
uploadSize: { type: Number, default: 100 }, //上传文件大小
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
uploadData: { type: Object, default: {} },
|
||||
fileName: {
|
||||
type: String,
|
||||
default: 'file'
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const baseURL: string | undefined | boolean = import.meta.env.VITE_APP_BASE_API_GO;
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const token = proxy?.$cache.local.get('goToken');
|
||||
const dialogImageUrl = ref('');
|
||||
const elUploadRef = ref<UploadInstance>();
|
||||
const dialogVisible = ref(false);
|
||||
const imageUrl = ref('');
|
||||
const state = reactive({
|
||||
fileName: props.fileName
|
||||
});
|
||||
const headers = reactive({
|
||||
Authorization: 'Bearer ' + token,
|
||||
...sign({ token: token, ...props.uploadData })
|
||||
});
|
||||
const dataParam = reactive({
|
||||
token: token,
|
||||
...props.uploadData
|
||||
});
|
||||
let uploadedFile: Array<any> = [];
|
||||
const dataFileList = computed({
|
||||
get: () => {
|
||||
let value: Array<UploadUserFile> = (props.modelValue as UploadUserFile[]) || [];
|
||||
if (value.length) {
|
||||
value.map((item: UploadUserFile) => {
|
||||
if (item.url) {
|
||||
// item.url = proxy.getUpFileUrl(item.url);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
uploadedFile = _.cloneDeep(value);
|
||||
return value;
|
||||
},
|
||||
set: (val) => {
|
||||
emit('uploadData', val);
|
||||
}
|
||||
});
|
||||
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
||||
if (rawFile.type.substring(0, 5) !== 'image') {
|
||||
ElMessage.error('请上传图片文件');
|
||||
return false;
|
||||
} else if (rawFile.size / 1024 / 1024 > props.uploadSize) {
|
||||
ElMessage.error('上传文件超过' + props.uploadSize + 'M');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const handleRemove: UploadProps['onRemove'] = (file) => {
|
||||
uploadedFile.splice(
|
||||
uploadedFile.findIndex((item: any) => item.uid === file.uid),
|
||||
1
|
||||
);
|
||||
setDataFileList();
|
||||
};
|
||||
const handleExceed = (files) => {
|
||||
elUploadRef.value!.clearFiles();
|
||||
const file = files[0];
|
||||
file.uid = genFileId();
|
||||
elUploadRef.value!.handleStart(file);
|
||||
elUploadRef.value!.submit();
|
||||
// ElMessage.error('最多可上传' + props.limit + '个文件,已超出最大限制数。');
|
||||
};
|
||||
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
||||
dialogImageUrl.value = uploadFile.url!;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
|
||||
emit('uploadImageAuth', response); //返回认证的数据
|
||||
if (props.limit == 1) {
|
||||
uploadedFile = [];
|
||||
imageUrl.value = URL.createObjectURL(uploadFile.raw!);
|
||||
}
|
||||
uploadedFile = uploadedFile.filter((item: UploadUserFile) => {
|
||||
return item.raw?.uid != uploadFile.raw?.uid;
|
||||
});
|
||||
if (response.code === 0) {
|
||||
// if (response.data.name) {
|
||||
// uploadedFile.push({
|
||||
// // 单图
|
||||
// name: response.data.name,
|
||||
// url: response.data.path,
|
||||
// fileType: response.data.type,
|
||||
// size: response.data.size,
|
||||
// });
|
||||
// } else {
|
||||
// console.log(response.data);
|
||||
// if (response.data.list) {
|
||||
// uploadedFile.push({
|
||||
// // 多图
|
||||
// name: response.data.list[0].name,
|
||||
// url: response.data.list[0].path,
|
||||
// fileType: response.data.list[0].type,
|
||||
// size: response.data.list[0].size,
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
uploadedFile.push({
|
||||
// 多图
|
||||
name: response.data[0].name,
|
||||
url: response.data[0].path,
|
||||
fileType: response.data[0].type,
|
||||
size: response.data[0].size
|
||||
});
|
||||
// }
|
||||
|
||||
setDataFileList();
|
||||
} else {
|
||||
ElMessage.error(response.message);
|
||||
imageUrl.value = '';
|
||||
}
|
||||
emit('uploadImageAuth1', uploadedFile); //返回认证的数据
|
||||
};
|
||||
const setDataFileList = () => {
|
||||
dataFileList.value = uploadedFile;
|
||||
};
|
||||
return {
|
||||
dataFileList,
|
||||
imageUrl,
|
||||
baseURL,
|
||||
dialogVisible,
|
||||
dialogImageUrl,
|
||||
handleExceed,
|
||||
beforeAvatarUpload,
|
||||
handleRemove,
|
||||
handlePictureCardPreview,
|
||||
handleAvatarSuccess,
|
||||
dataParam,
|
||||
headers,
|
||||
elUploadRef,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.up-img :deep(.avatar-uploader .avatar) {
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
display: block;
|
||||
}
|
||||
.up-img :deep(.avatar-uploader .el-upload) {
|
||||
border: 1px dashed var(--el-border-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
}
|
||||
|
||||
.up-img :deep(.avatar-uploader .el-upload:hover) {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.up-img :deep(.el-icon.avatar-uploader-icon) {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 178px;
|
||||
height: 178px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
@ -17,7 +17,7 @@
|
||||
<template v-if="item.meta" #title>
|
||||
<svg-icon :icon-class="item.meta ? item.meta.icon : ''" />
|
||||
<span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span>
|
||||
<span class="bage" v-if="item.meta?.title == '我的任务' && total > 0">{{ total }}</span>
|
||||
<span class="bage" v-if="item.meta?.title == '我的任务' && total + totalChao > 0">{{ total + totalChao }}</span>
|
||||
</template>
|
||||
|
||||
<sidebar-item
|
||||
@ -61,6 +61,7 @@ const totalChao = ref(0);
|
||||
onMounted(() => {
|
||||
if (onlyOneChild.value.meta?.title == '我的待办' || props.item.meta?.title == '我的任务') {
|
||||
getWaitingList();
|
||||
getChaoList();
|
||||
}
|
||||
if (onlyOneChild.value.meta?.title == '我的抄送') {
|
||||
getChaoList();
|
||||
|
@ -9,7 +9,7 @@ import animate from '@/animate';
|
||||
import { download as dl } from '@/utils/request';
|
||||
import { useDict } from '@/utils/dict';
|
||||
import { getConfigKey, updateConfigByKey } from '@/api/system/config';
|
||||
import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi';
|
||||
import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels,formatPrice } from '@/utils/ruoyi';
|
||||
import { downloadFile } from '@/utils/useFileDownload';
|
||||
|
||||
import { App } from 'vue';
|
||||
@ -42,4 +42,5 @@ export default function installPlugin(app: App) {
|
||||
app.config.globalProperties.selectDictLabels = selectDictLabels;
|
||||
app.config.globalProperties.animate = animate;
|
||||
app.config.globalProperties.downloadFile = downloadFile;
|
||||
app.config.globalProperties.formatPrice = formatPrice;
|
||||
}
|
||||
|
@ -72,9 +72,15 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
component: () => import('@/views/error/401.vue'),
|
||||
hidden: true
|
||||
},
|
||||
|
||||
{
|
||||
path: '/ProjectScreen',
|
||||
component: () => import('@/views/ProjectScreen/index.vue'),
|
||||
component: () => import('@/views/projectLarge/ProjectScreen/index.vue'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/digitalizationScreen',
|
||||
component: () => import('@/views/enterpriseLarge/digitalizationScreen/index.vue'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
|
@ -70,9 +70,11 @@ const exceptionStr = '/api/v1/test/'; // /api/v1/test/*接口拦截
|
||||
service.interceptors.request.use(
|
||||
(config: any) => {
|
||||
// 在发送请求之前做些什么 token
|
||||
|
||||
if (token) {
|
||||
config.headers = config.headers || {};
|
||||
(config.headers as any)['Authorization'] = `Bearer ${token}`;
|
||||
console.log('🚀 ~ config.headers:', config.headers);
|
||||
}
|
||||
const stores = useUserStore();
|
||||
if (!whiteUrl.includes(config.url) && !config.url.includes(exceptionStr)) {
|
||||
|
@ -62,7 +62,23 @@ export const addDateRange = (params: any, dateRange: any[], propName?: string) =
|
||||
}
|
||||
return search;
|
||||
};
|
||||
// 价格格式化函数
|
||||
export const formatPrice = (price, show = true) => {
|
||||
if ((!show && price == 0) || price == '' || price == undefined || price == null) return '';
|
||||
if (!price && price !== 0) return '0.0000';
|
||||
|
||||
// 转换为数字并保留四位小数
|
||||
const num = Number(price);
|
||||
if (isNaN(num)) return '0.0000';
|
||||
|
||||
const fixedNum = num.toFixed(4);
|
||||
const [integer, decimal] = fixedNum.split('.');
|
||||
|
||||
// 千分位处理
|
||||
const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
|
||||
return `${formattedInteger}.${decimal}`;
|
||||
};
|
||||
// 回显数据字典
|
||||
export const selectDictLabel = (datas: any, value: number | string) => {
|
||||
if (value === undefined) {
|
||||
|
@ -62,14 +62,14 @@
|
||||
<el-table-column prop="unit" label="单位" align="center" />
|
||||
<el-table-column prop="quantity" label="数量" align="center" />
|
||||
<el-table-column prop="specification" label="规格" align="center" />
|
||||
<el-table-column prop="remark" label="单价" align="center">
|
||||
<el-table-column label="单价" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.unitPrice }}</span>
|
||||
{{ proxy.formatPrice(scope.row.unitPrice) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.price }}
|
||||
{{ proxy.formatPrice(scope.row.price) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column prop="price" label="操作" align="center">
|
||||
@ -92,7 +92,7 @@
|
||||
<script setup lang="ts">
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { BiddingImportExcelFile, getTreeLimit, biddingLimitListUpdate, sheetList, obtainAllVersionNumbers } from '@/api/bidding/biddingLimit';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
|
||||
const userStore = useUserStoreHook();
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
|
232
src/views/busMachineryDetail/list/component/add.vue
Normal file
@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<div class="system-busMachineryDetail-add">
|
||||
<el-dialog v-model="isShowDialog" width="769px" :close-on-click-modal="false" :destroy-on-close="true">
|
||||
<template #header>
|
||||
<div v-drag="['.system-busMachineryDetail-add .el-dialog', '.system-busMachineryDetail-add .el-dialog__header']">添加机械入场记录</div>
|
||||
</template>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="130px">
|
||||
<el-row>
|
||||
<el-col :span="12"
|
||||
><el-form-item label="合格证编号" prop="checkoutNumber">
|
||||
<el-input v-model="formData.checkoutNumber" placeholder="请输入合格证编号" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="12"
|
||||
><el-form-item label="生产厂家" prop="checkoutUnit">
|
||||
<el-input v-model="formData.checkoutUnit" placeholder="请输入生产厂家" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="12"
|
||||
><el-form-item label="生产日期/有效期" prop="checkoutDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
style="width: 250px"
|
||||
v-model="formData.checkoutDate"
|
||||
type="datetime"
|
||||
placeholder="选择检定日期/有效期"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
:disabled-date="disabledDate"
|
||||
>
|
||||
</el-date-picker> </el-form-item
|
||||
></el-col>
|
||||
<!-- <el-radio v-for="dict in typeOptions" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> -->
|
||||
<!-- <el-col :span="12"
|
||||
><el-form-item label="出入场" prop="type">
|
||||
<el-radio-group v-model="formData.type">
|
||||
<el-radio label="2">入场</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item></el-col
|
||||
> -->
|
||||
<el-col :span="12"
|
||||
><el-form-item label="施工类型状态" prop="status">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio v-for="dict in statusOptions" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item></el-col
|
||||
>
|
||||
<el-col :span="12"
|
||||
><el-form-item label="入场时间" prop="entryTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
style="width: 250px"
|
||||
v-model="formData.entryTime"
|
||||
type="datetime"
|
||||
placeholder="选择入场时间"
|
||||
format="YYYY年MM月DD日 hh时mm分ss秒"
|
||||
value-format="YYYY-MM-DD hh:mm:ss"
|
||||
>
|
||||
</el-date-picker> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="24"
|
||||
><el-form-item label="备注" prop="remark"> <el-input v-model="formData.remark" placeholder="请输入备注" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="图片" prop="picture">
|
||||
<upload-img :action="baseURL + '/zm/api/v1/system/upload/multipleImg'" @uploadImageAuth1="setUpImgListPicture($event)" :limit="4">
|
||||
</upload-img> </el-form-item
|
||||
></el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="onSubmit">确 定</el-button>
|
||||
<el-button @click="onCancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { reactive, toRefs, defineComponent, ref, unref, getCurrentInstance } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { addBusMachineryDetail } from '@/api/machinery/machineryDetail';
|
||||
import uploadImg from '@/components/uploadImg/index.vue';
|
||||
import { BusMachineryDetailEditState } from './model';
|
||||
import { stat } from 'fs';
|
||||
export default defineComponent({
|
||||
name: 'index',
|
||||
components: {
|
||||
uploadImg
|
||||
},
|
||||
props: {
|
||||
statusOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const baseURL: string | undefined | boolean = import.meta.env.VITE_APP_BASE_API_GO;
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const formRef = ref<HTMLElement | null>(null);
|
||||
const menuRef = ref();
|
||||
const state = reactive<BusMachineryDetailEditState>({
|
||||
loading: false,
|
||||
isShowDialog: false,
|
||||
typeOptions: [
|
||||
{ value: '2', label: '入场' },
|
||||
{ value: '1', label: '出场' }
|
||||
],
|
||||
formData: {
|
||||
id: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
entryTime: undefined,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
remark: undefined,
|
||||
picture: [],
|
||||
type: '2'
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
checkoutNumber: [{ required: true, message: '检验证编号不能为空', trigger: 'blur' }],
|
||||
checkoutUnit: [{ required: true, message: '检验单位不能为空', trigger: 'blur' }],
|
||||
checkoutDate: [{ required: true, message: '检定日期/有效期不能为空', trigger: 'blur' }],
|
||||
type: [{ required: true, message: '出入场不能为空', trigger: 'blur' }]
|
||||
},
|
||||
imageList: [],
|
||||
propsRow: {}
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row: any) => {
|
||||
resetForm();
|
||||
if (row) {
|
||||
state.formData.machinery_id = row.id;
|
||||
state.propsRow = row;
|
||||
}
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
// 去重
|
||||
// state.formData.picture = state.formData.picture.join(',');
|
||||
const formWrap = unref(formRef) as any;
|
||||
if (!formWrap) return;
|
||||
formWrap.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
state.loading = true;
|
||||
//添加
|
||||
state.formData.type = '2';
|
||||
addBusMachineryDetail(state.formData)
|
||||
.then(() => {
|
||||
ElMessage.success('添加成功');
|
||||
closeDialog(); // 关闭弹窗
|
||||
emit('busMachineryDetailList', state.propsRow.children, state.propsRow.id);
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
const resetForm = () => {
|
||||
state.formData = {
|
||||
id: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
entryTime: undefined,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
remark: undefined,
|
||||
picture: []
|
||||
};
|
||||
};
|
||||
const setUpImgListPicture = (val: any) => {
|
||||
// console.log(val);
|
||||
// if (val.length > 0 && val[0].url && !val[0].raw) {
|
||||
// let path = '';
|
||||
// val.forEach((item) => {
|
||||
// // 判断是否存在http
|
||||
// if (item.url.indexOf('http') != -1) {
|
||||
// path = path + ',' + item.url.slice(item.url.indexOf('/upload_file') + 1);
|
||||
// } else {
|
||||
// path = path + ',' + item.url;
|
||||
// }
|
||||
// });
|
||||
// path = path.slice(1);
|
||||
state.formData.picture = [];
|
||||
val.forEach((item) => {
|
||||
state.formData.picture.push(item.url);
|
||||
});
|
||||
// }
|
||||
};
|
||||
const disabledDate = (time) => {
|
||||
return time.getTime() >= Date.now(); // 8.64e7 毫秒数代表一天
|
||||
};
|
||||
return {
|
||||
proxy,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
menuRef,
|
||||
formRef,
|
||||
setUpImgListPicture,
|
||||
baseURL,
|
||||
disabledDate,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-col {
|
||||
margin: 10px 0 !important;
|
||||
}
|
||||
</style>
|
219
src/views/busMachineryDetail/list/component/detail.vue
Normal file
@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<!-- 机械详情详情抽屉 -->
|
||||
<div class="system-busMachineryDetail-detail">
|
||||
<el-drawer v-model="isShowDialog" class="busMachineryDetail_detail" size="40%" direction="ltr">
|
||||
<template #header>
|
||||
<h4>机械出入场记录详情</h4>
|
||||
</template>
|
||||
<el-form ref="formRef" :model="formData" label-width="130px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合格证编号">{{ formData.checkoutNumber }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生产厂家">{{ formData.checkoutUnit }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生产日期/有效期">{{ formData.checkoutDate }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="出入场">{{ formData.type == 1 ? '出场' : formData.type == 2 ? '入场' : '' }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="施工类型状态">{{ getOptionValue(formData.status, statusOptions, 'value', 'label') }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="入场时间">{{ formData.entryTime }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建时间">{{ formData.createdAt }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">{{ formData.remark }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="图片">
|
||||
<div class="pic-block" v-if="formData.picture.length" v-for="(img, key) in formData.picture" :key="'picture-' + key">
|
||||
<el-image
|
||||
style="width: 140px; height: 150px; margin: 0 5px"
|
||||
v-if="img"
|
||||
:src="'http://58.17.134.85:8920' + img"
|
||||
fit="contain"
|
||||
:preview-src-list="['http://58.17.134.85:8920' + img]"
|
||||
:zoom-rate="1.2"
|
||||
preview-teleported="true"
|
||||
></el-image>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-table v-loading="loading" :data="formData.recordList">
|
||||
<el-table-column label="出入场" align="center" prop="type">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.type == 1">出场</span>
|
||||
<span v-if="scope.row.type == 2">入场</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="施工类型状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.status == 0">正常</span>
|
||||
<span v-if="scope.row.status == 1">停用</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="填报人" align="center" prop="createdBy" min-width="100px" /> -->
|
||||
<el-table-column label="记录时间" align="center" prop="recordTime">
|
||||
<template #default="scope">
|
||||
<span>{{ proxy.parseTime(scope.row.recordTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { reactive, toRefs, defineComponent, ref, getCurrentInstance } from 'vue';
|
||||
import { getBusMachineryDetail } from '@/api/machinery/machineryDetail';
|
||||
import { ElLoading } from 'element-plus';
|
||||
import uploadImg from '@/components/uploadImg/index.vue';
|
||||
import { BusMachineryDetailInfoData, BusMachineryDetailEditState } from './model';
|
||||
export default defineComponent({
|
||||
name: 'index',
|
||||
components: {
|
||||
uploadImg
|
||||
},
|
||||
props: {
|
||||
statusOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const baseURL: string | undefined | boolean = import.meta.env.VITE_API_URL;
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const formRef = ref<HTMLElement | null>(null);
|
||||
const menuRef = ref();
|
||||
const state = reactive<BusMachineryDetailEditState>({
|
||||
loading: false,
|
||||
isShowDialog: false,
|
||||
formData: {
|
||||
id: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
entryTime: undefined,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
remark: undefined,
|
||||
picture: []
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
id: [{ required: true, message: '序号不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '施工类型状态不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row?: BusMachineryDetailInfoData) => {
|
||||
resetForm();
|
||||
if (row) {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '正在加载中……',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
target: '.busMachineryDetail_detail'
|
||||
});
|
||||
getBusMachineryDetail(row.id!).then((res: any) => {
|
||||
loading.close();
|
||||
const data = res.data;
|
||||
state.formData = data;
|
||||
if (state.formData.picture && state.formData.picture.includes('[')) {
|
||||
state.formData.picture = state.formData.picture ? JSON.parse(state.formData.picture) : [];
|
||||
} else {
|
||||
state.formData.picture = state.formData.picture ? state.formData.picture.split(',') : [];
|
||||
}
|
||||
});
|
||||
}
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
const resetForm = () => {
|
||||
state.formData = {
|
||||
id: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
entryTime: undefined,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
remark: undefined,
|
||||
picture: []
|
||||
};
|
||||
};
|
||||
function getOptionValue(key: any, options: Array<any>, keyName: string, valName: string) {
|
||||
keyName = keyName ?? 'key';
|
||||
valName = valName ?? 'value';
|
||||
const option = options.find((value) => {
|
||||
return key + '' === value[keyName];
|
||||
});
|
||||
if (option !== undefined) {
|
||||
return option[valName];
|
||||
}
|
||||
}
|
||||
const setUpImgListPicture = (data: any) => {
|
||||
state.formData.picture = data;
|
||||
};
|
||||
return {
|
||||
proxy,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
menuRef,
|
||||
getOptionValue,
|
||||
formRef,
|
||||
setUpImgListPicture,
|
||||
baseURL,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.system-busMachineryDetail-detail :deep(.el-form-item--large .el-form-item__label) {
|
||||
font-weight: bolder;
|
||||
}
|
||||
.pic-block {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.file-block {
|
||||
width: 100%;
|
||||
border: 1px solid var(--el-border-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
margin-bottom: 5px;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
.ml-2 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
253
src/views/busMachineryDetail/list/component/edit.vue
Normal file
@ -0,0 +1,253 @@
|
||||
<template>
|
||||
<div class="system-busMachineryDetail-edit">
|
||||
<el-dialog v-model="isShowDialog" width="769px" :close-on-click-modal="false" :destroy-on-close="true" custom-class="busMachineryDetail_edit">
|
||||
<template #header>
|
||||
<div v-drag="['.system-busMachineryDetail-edit .el-dialog', '.system-busMachineryDetail-edit .el-dialog__header']">
|
||||
{{ formData.id ? '修改' : '添加' }}机械出入场记录
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="130px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合格证编号" prop="checkoutNumber">
|
||||
<el-input v-model="formData.checkoutNumber" placeholder="请输入合格证编号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生产厂家" prop="checkoutUnit">
|
||||
<el-input v-model="formData.checkoutUnit" placeholder="请输入生产厂家" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生产日期/有效期" prop="checkoutDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
style="width: 250px"
|
||||
v-model="formData.checkoutDate"
|
||||
type="datetime"
|
||||
placeholder="选择检定日期/有效期"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
:disabled-date="disabledDate"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="出入场" prop="type">
|
||||
<el-radio-group v-model="formData.type">
|
||||
<el-radio v-for="dict in typeOptions" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="施工类型状态" prop="status">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio v-for="dict in statusOptions" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="出入场时间" prop="entryTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
style="width: 250px"
|
||||
v-model="formData.entryTime"
|
||||
type="datetime"
|
||||
placeholder="选择入场时间"
|
||||
format="YYYY年MM月DD日 hh时mm分ss秒"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="图片" prop="picture">
|
||||
<UploadImg
|
||||
:action="baseURL + '/zm/api/v1/system/upload/multipleImg'"
|
||||
v-model="formData.picture"
|
||||
@uploadData="setUpImgListPicture"
|
||||
:limit="4"
|
||||
ref="uploadRef"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="onSubmit">确 定</el-button>
|
||||
<el-button @click="onCancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { reactive, ref, toRefs, defineComponent, unref } from 'vue';
|
||||
import { ElMessage, ElLoading } from 'element-plus';
|
||||
import { getBusMachineryDetail, addBusMachineryDetail, updateBusMachineryDetail } from '@/api/machinery/machineryDetail';
|
||||
import UploadImg from '@/components/uploadImg/index.vue';
|
||||
import { BusMachineryDetailInfoData, BusMachineryDetailEditState } from './model';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'editMachineChild',
|
||||
components: { UploadImg },
|
||||
props: {
|
||||
statusOptions: { type: Array, default: () => [] }
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const baseURL = import.meta.env.VITE_APP_BASE_API_GO;
|
||||
const formRef = ref(null);
|
||||
const uploadRef = ref(null);
|
||||
|
||||
const state = reactive<BusMachineryDetailEditState>({
|
||||
loading: false,
|
||||
isShowDialog: false,
|
||||
typeOptions: [
|
||||
{ value: '2', label: '入场' },
|
||||
{ value: '1', label: '出场' }
|
||||
],
|
||||
formData: {
|
||||
id: undefined,
|
||||
checkoutNumber: '',
|
||||
checkoutUnit: '',
|
||||
checkoutDate: undefined,
|
||||
type: '',
|
||||
status: '',
|
||||
entryTime: undefined,
|
||||
remark: '',
|
||||
picture: []
|
||||
},
|
||||
propsRow: {},
|
||||
rules: {
|
||||
checkoutNumber: [{ required: true, message: '检验证编号不能为空', trigger: 'blur' }],
|
||||
checkoutUnit: [{ required: true, message: '检验单位不能为空', trigger: 'blur' }],
|
||||
checkoutDate: [{ required: true, message: '检定日期/有效期不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '施工类型状态不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const resetForm = () => {
|
||||
Object.assign(state.formData, {
|
||||
id: undefined,
|
||||
checkoutNumber: '',
|
||||
checkoutUnit: '',
|
||||
checkoutDate: undefined,
|
||||
type: '',
|
||||
status: '',
|
||||
entryTime: undefined,
|
||||
remark: '',
|
||||
picture: []
|
||||
});
|
||||
if (uploadRef.value) {
|
||||
uploadRef.value.clearFiles && uploadRef.value.clearFiles(); // 清空上传组件历史
|
||||
}
|
||||
};
|
||||
|
||||
const openDialog = (props: any, row?: BusMachineryDetailInfoData) => {
|
||||
resetForm();
|
||||
if (props) state.propsRow = props;
|
||||
|
||||
if (row) {
|
||||
const loadingInstance = ElLoading.service({
|
||||
lock: true,
|
||||
text: '正在加载中……',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
target: '.busMachineryDetail_edit'
|
||||
});
|
||||
getBusMachineryDetail(row.id!).then((res: any) => {
|
||||
loadingInstance.close();
|
||||
const data = res.data;
|
||||
let pictureArr: any[] = [];
|
||||
|
||||
if (data.picture) {
|
||||
if (data.picture.includes('[')) {
|
||||
data.picture = JSON.parse(data.picture);
|
||||
} else {
|
||||
data.picture = data.picture.split(',');
|
||||
}
|
||||
pictureArr = data.picture.map((item, index) => ({
|
||||
url: 'http://58.17.134.85:8920' + item,
|
||||
name: `img_${index}`
|
||||
}));
|
||||
}
|
||||
|
||||
Object.assign(state.formData, {
|
||||
...data,
|
||||
type: data.type ?? '',
|
||||
status: data.status ?? '',
|
||||
picture: pictureArr
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
const onCancel = () => closeDialog();
|
||||
|
||||
const setUpImgListPicture = (val: any) => {
|
||||
state.formData.picture.splice(0, state.formData.picture.length, ...val);
|
||||
};
|
||||
|
||||
const pictureConvert = () => {
|
||||
if (Array.isArray(state.formData.picture)) {
|
||||
state.formData.picture = state.formData.picture.map((item) => item.url.substring(item.url.indexOf('/file')));
|
||||
}
|
||||
};
|
||||
|
||||
const onSubmit = () => {
|
||||
pictureConvert();
|
||||
const formWrap = unref(formRef) as any;
|
||||
if (!formWrap) return;
|
||||
|
||||
formWrap.validate((valid: boolean) => {
|
||||
if (!valid) return;
|
||||
|
||||
state.loading = true;
|
||||
const apiCall = state.formData.id ? updateBusMachineryDetail : addBusMachineryDetail;
|
||||
|
||||
apiCall(state.formData)
|
||||
.then(() => {
|
||||
ElMessage.success(state.formData.id ? '修改成功' : '添加成功');
|
||||
closeDialog();
|
||||
emit('busMachineryDetailList', state.propsRow.children, state.propsRow.id);
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const disabledDate = (time: Date) => time.getTime() >= Date.now();
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
formRef,
|
||||
uploadRef,
|
||||
baseURL,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
setUpImgListPicture,
|
||||
disabledDate
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-col {
|
||||
margin: 10px 0 !important;
|
||||
}
|
||||
</style>
|
55
src/views/busMachineryDetail/list/component/model.ts
Normal file
@ -0,0 +1,55 @@
|
||||
export interface BusMachineryDetailTableColumns {
|
||||
id:number; // 序号
|
||||
checkoutNumber:string; // 检验证编号
|
||||
checkoutUnit:string; // 检验单位
|
||||
checkoutDate:string; // 检定日期/有效期
|
||||
status:string; // 施工类型状态
|
||||
entryTime:string; // 入场时间
|
||||
createdAt:string; // 创建时间
|
||||
remark:string; // 备注
|
||||
picture:any[]; // 4张图片,逗号分隔
|
||||
}
|
||||
|
||||
|
||||
export interface BusMachineryDetailInfoData {
|
||||
id:number|undefined; // 序号
|
||||
checkoutNumber:string|undefined; // 检验证编号
|
||||
checkoutUnit:string|undefined; // 检验单位
|
||||
checkoutDate:string|undefined; // 检定日期/有效期
|
||||
status:string|undefined; // 施工类型状态
|
||||
entryTime:string|undefined; // 入场时间
|
||||
createBy:string|undefined; // 创建者
|
||||
updateBy:string|undefined; // 更新者
|
||||
createdAt:string|undefined; // 创建时间
|
||||
updatedAt:string|undefined; // 更新时间
|
||||
deletedAt:string|undefined; // 删除时间
|
||||
remark:string|undefined; // 备注
|
||||
picture:any[]; // 4张图片,逗号分隔
|
||||
type: undefined, // 出入场
|
||||
}
|
||||
|
||||
|
||||
export interface BusMachineryDetailTableDataState {
|
||||
ids:any[];
|
||||
tableData: {
|
||||
data: Array<BusMachineryDetailTableColumns>;
|
||||
total: number;
|
||||
loading: boolean;
|
||||
param: {
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
checkoutNumber: string|undefined;
|
||||
status: string|undefined;
|
||||
entryTime: string|undefined;
|
||||
dateRange: string[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export interface BusMachineryDetailEditState{
|
||||
loading:boolean;
|
||||
isShowDialog: boolean;
|
||||
formData:BusMachineryDetailInfoData;
|
||||
rules: object;
|
||||
}
|
339
src/views/busMachineryDetail/list/index.vue
Normal file
@ -0,0 +1,339 @@
|
||||
<template>
|
||||
<div class="system-busMachineryDetail-container">
|
||||
<el-card shadow="hover">
|
||||
<div class="system-busMachineryDetail-search mb15">
|
||||
<el-form :model="tableData.param" ref="queryRef" :inline="true" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="8" class="colBlock">
|
||||
<el-form-item label="合格证编号" prop="checkoutNumber">
|
||||
<el-input
|
||||
v-model="tableData.param.checkoutNumber"
|
||||
placeholder="请输入合格证编号"
|
||||
clearable
|
||||
@keyup.enter.native="busMachineryDetailList"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="colBlock">
|
||||
<el-form-item label="施工类型状态" prop="status">
|
||||
<el-select v-model="tableData.param.status" placeholder="请选择施工类型状态" clearable>
|
||||
<el-option v-for="dict in account_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" :class="!showAll ? 'colBlock' : 'colNone'">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="busMachineryDetailList"
|
||||
><el-icon><Search /></el-icon>搜索</el-button
|
||||
>
|
||||
<el-button @click="resetQuery(queryRef)"
|
||||
><el-icon><Refresh /></el-icon>重置</el-button
|
||||
>
|
||||
<el-button type="primary" link @click="toggleSearch">
|
||||
{{ word }}
|
||||
<el-icon v-show="showAll"><ArrowUp /></el-icon>
|
||||
<el-icon v-show="!showAll"><ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" :class="showAll ? 'colBlock' : 'colNone'">
|
||||
<el-form-item label="入场时间" prop="entryTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
style="width: 200px"
|
||||
v-model="tableData.param.entryTime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="datetime"
|
||||
placeholder="选择入场时间"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" :class="showAll ? 'colBlock' : 'colNone'">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="busMachineryDetailList"
|
||||
><el-icon><Search /></el-icon>搜索</el-button
|
||||
>
|
||||
<el-button @click="resetQuery(queryRef)"
|
||||
><el-icon><Refresh /></el-icon>重置</el-button
|
||||
>
|
||||
<el-button type="primary" link @click="toggleSearch">
|
||||
{{ word }}
|
||||
<el-icon v-show="showAll"><ArrowUp /></el-icon>
|
||||
<el-icon v-show="!showAll"><ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" @click="handleAdd" v-auth="'api/v1/system/busMachineryDetail/add'"
|
||||
><el-icon><Plus /></el-icon>新增</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" :disabled="single" @click="handleUpdate(null)" v-auth="'api/v1/system/busMachineryDetail/edit'"
|
||||
><el-icon><Edit /></el-icon>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" :disabled="multiple" @click="handleDelete(null)" v-auth="'api/v1/system/busMachineryDetail/delete'"
|
||||
><el-icon><Delete /></el-icon>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-table v-loading="loading" :data="tableData.data" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="序号" align="center" type="index" :index="indexMethod" width="60" />
|
||||
<el-table-column label="合格证编号" align="center" prop="checkoutNumber" min-width="100px" />
|
||||
<el-table-column label="生产厂家" align="center" prop="checkoutUnit" min-width="100px" />
|
||||
<el-table-column label="检定日期/有效期" align="center" prop="checkoutDate" min-width="100px">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.checkoutDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="施工类型状态" align="center" prop="status" :formatter="statusFormat" min-width="100px" />
|
||||
<el-table-column label="入场时间" align="center" prop="entryTime" min-width="100px">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.entryTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createdAt" min-width="100px">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.createdAt }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" min-width="100px" />
|
||||
<el-table-column label="图片" align="center" prop="picture" min-width="100px">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<el-image
|
||||
style="width: 100px; height: 50px"
|
||||
:initial-index="1"
|
||||
v-if="scope.row.image"
|
||||
:src="'http://58.17.134.85:8920' + scope.row.image"
|
||||
fit="contain"
|
||||
:preview-src-list="['http://58.17.134.85:8920' + scope.row.picture]"
|
||||
:z-index="999999999"
|
||||
></el-image>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding" min-width="160px">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="handleUpdate(scope.row)"
|
||||
><el-icon><EditPen /></el-icon>修改</el-button
|
||||
>
|
||||
<el-button type="primary" link @click="handleDelete(scope.row)"
|
||||
><el-icon><DeleteFilled /></el-icon>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:total="tableData.total"
|
||||
v-model:page="tableData.param.pageNum"
|
||||
v-model:limit="tableData.param.pageSize"
|
||||
@pagination="busMachineryDetailList"
|
||||
/>
|
||||
</el-card>
|
||||
<apiV1SystemBusMachineryDetailAdd
|
||||
ref="addRef"
|
||||
:statusOptions="account_status"
|
||||
@busMachineryDetailList="busMachineryDetailList"
|
||||
></apiV1SystemBusMachineryDetailAdd>
|
||||
<apiV1SystemBusMachineryDetailEdit
|
||||
ref="editRef"
|
||||
:statusOptions="account_status"
|
||||
@busMachineryDetailList="busMachineryDetailList"
|
||||
></apiV1SystemBusMachineryDetailEdit>
|
||||
<apiV1SystemBusMachineryDetailDetail
|
||||
ref="detailRef"
|
||||
:statusOptions="account_status"
|
||||
@busMachineryDetailList="busMachineryDetailList"
|
||||
></apiV1SystemBusMachineryDetailDetail>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted, ref, defineComponent, computed, getCurrentInstance, toRaw } from 'vue';
|
||||
import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
|
||||
import { listBusMachineryDetail, delBusMachineryDetail } from '@/api/machinery/machineryDetail';
|
||||
import { BusMachineryDetailTableColumns, BusMachineryDetailInfoData, BusMachineryDetailTableDataState } from './component/model';
|
||||
import apiV1SystemBusMachineryDetailAdd from './component/add.vue';
|
||||
import apiV1SystemBusMachineryDetailEdit from './component/edit.vue';
|
||||
import apiV1SystemBusMachineryDetailDetail from './component/detail.vue';
|
||||
export default defineComponent({
|
||||
name: 'index',
|
||||
components: {
|
||||
apiV1SystemBusMachineryDetailAdd,
|
||||
apiV1SystemBusMachineryDetailEdit,
|
||||
apiV1SystemBusMachineryDetailDetail
|
||||
},
|
||||
setup() {
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const queryRef = ref();
|
||||
const addRef = ref();
|
||||
const editRef = ref();
|
||||
const detailRef = ref();
|
||||
// 是否显示所有搜索选项
|
||||
const showAll = ref(false);
|
||||
// 非单个禁用
|
||||
const single = ref(true);
|
||||
// 非多个禁用
|
||||
const multiple = ref(true);
|
||||
const word = computed(() => {
|
||||
if (showAll.value === false) {
|
||||
//对文字进行处理
|
||||
return '展开搜索';
|
||||
} else {
|
||||
return '收起搜索';
|
||||
}
|
||||
});
|
||||
// 字典选项数据
|
||||
const { account_status } = proxy.useDict('account_status');
|
||||
const state = reactive<BusMachineryDetailTableDataState>({
|
||||
ids: [],
|
||||
tableData: {
|
||||
data: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
param: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
checkoutNumber: undefined,
|
||||
status: undefined,
|
||||
entryTime: undefined,
|
||||
dateRange: []
|
||||
}
|
||||
}
|
||||
});
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
busMachineryDetailList();
|
||||
};
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
busMachineryDetailList();
|
||||
};
|
||||
// 获取列表数据
|
||||
const busMachineryDetailList = () => {
|
||||
loading.value = true;
|
||||
listBusMachineryDetail(state.tableData.param).then((res: any) => {
|
||||
let list = res.data.list ?? [];
|
||||
state.tableData.data = list;
|
||||
state.tableData.data.forEach((item) => {
|
||||
if (item.picture) {
|
||||
item.image = item.picture.split(',')[0];
|
||||
item.imageList = item.picture.split(',');
|
||||
}
|
||||
});
|
||||
state.tableData.total = res.data.total;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const toggleSearch = () => {
|
||||
showAll.value = !showAll.value;
|
||||
};
|
||||
// 施工类型状态字典翻译
|
||||
const statusFormat = (row: BusMachineryDetailTableColumns) => {
|
||||
return proxy.selectDictLabel(account_status.value, row.status);
|
||||
};
|
||||
// 多选框选中数据
|
||||
const handleSelectionChange = (selection: Array<BusMachineryDetailInfoData>) => {
|
||||
state.ids = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
const handleAdd = () => {
|
||||
addRef.value.openDialog();
|
||||
};
|
||||
const handleUpdate = (row: BusMachineryDetailTableColumns) => {
|
||||
if (!row) {
|
||||
row = state.tableData.data.find((item: BusMachineryDetailTableColumns) => {
|
||||
return item.id === state.ids[0];
|
||||
}) as BusMachineryDetailTableColumns;
|
||||
}
|
||||
editRef.value.openDialog(toRaw(row));
|
||||
};
|
||||
const handleDelete = (row: BusMachineryDetailTableColumns) => {
|
||||
let msg = '你确定要删除所选数据?';
|
||||
let id: number[] = [];
|
||||
if (row) {
|
||||
msg = `此操作将永久删除数据,是否继续?`;
|
||||
id = [row.id];
|
||||
} else {
|
||||
id = state.ids;
|
||||
}
|
||||
if (id.length === 0) {
|
||||
ElMessage.error('请选择要删除的数据。');
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(msg, '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
delBusMachineryDetail(id).then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
busMachineryDetailList();
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
const handleView = (row: BusMachineryDetailTableColumns) => {
|
||||
detailRef.value.openDialog(toRaw(row));
|
||||
};
|
||||
/** 自定义编号 */
|
||||
const indexMethod = (index) => {
|
||||
let pageNum = state.tableData.param.pageNum - 1;
|
||||
if (pageNum !== -1 && pageNum !== 0) {
|
||||
return index + 1 + pageNum * state.tableData.param.pageSize;
|
||||
} else {
|
||||
return index + 1;
|
||||
}
|
||||
};
|
||||
return {
|
||||
proxy,
|
||||
addRef,
|
||||
editRef,
|
||||
detailRef,
|
||||
showAll,
|
||||
loading,
|
||||
single,
|
||||
multiple,
|
||||
word,
|
||||
queryRef,
|
||||
resetQuery,
|
||||
busMachineryDetailList,
|
||||
toggleSearch,
|
||||
statusFormat,
|
||||
account_status,
|
||||
handleSelectionChange,
|
||||
handleAdd,
|
||||
handleUpdate,
|
||||
handleDelete,
|
||||
indexMethod,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.colBlock {
|
||||
display: block;
|
||||
}
|
||||
.colNone {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
@ -77,8 +77,8 @@
|
||||
changePrice(scope.row);
|
||||
}
|
||||
"
|
||||
:precision="2"
|
||||
:step="0.1"
|
||||
:min="0"
|
||||
:precision="4"
|
||||
:controls="false"
|
||||
v-if="scope.row.quantity && scope.row.quantity != 0"
|
||||
/>
|
||||
@ -86,7 +86,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
|
||||
{{ proxy.formatPrice(scope.row.price) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="operate" label="操作" align="center">
|
||||
|
@ -25,7 +25,11 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" align="center" />
|
||||
<el-table-column prop="content" label="内容" align="center" />
|
||||
<el-table-column prop="price" label="限价" align="center" />
|
||||
<el-table-column prop="price" label="限价" align="center">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.price) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="plannedBiddingTime" align="center">
|
||||
<template #header> <span style="color: red">*</span>计划招标时间 </template>
|
||||
<template #default="scope">
|
||||
@ -158,22 +162,28 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="unitPrice" label="单价" align="center" />
|
||||
<el-table-column prop="unitPrice" label="单价" align="center">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.unitPrice) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<template #default="scope">
|
||||
{{
|
||||
proxy.formatPrice(
|
||||
((scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
|
||||
(scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
|
||||
Number(scope.row.unitPrice) ==
|
||||
0
|
||||
? ''
|
||||
: (
|
||||
((scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||
: ((scope.row.quantity ? Number(scope.row.quantity) : 0) -
|
||||
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
|
||||
(scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
|
||||
Number(scope.row.unitPrice)
|
||||
).toFixed(2)
|
||||
Number(scope.row.unitPrice),
|
||||
false
|
||||
)
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -207,6 +217,7 @@ import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { getDicts } from '@/api/system/dict/data';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { FormInstance } from 'element-plus';
|
||||
const { proxy } = getCurrentInstance();
|
||||
import {
|
||||
treeList,
|
||||
sheetList,
|
||||
|
@ -79,8 +79,8 @@
|
||||
changePrice(scope.row);
|
||||
}
|
||||
"
|
||||
:precision="2"
|
||||
:step="0.1"
|
||||
:min="0"
|
||||
:precision="4"
|
||||
:controls="false"
|
||||
v-if="scope.row.quantity && scope.row.quantity != 0"
|
||||
/>
|
||||
@ -88,9 +88,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<template #default="scope">
|
||||
<!-- {{ scope.row.children.length > 0 ? scope.row.children.reduce((sum, child) => sum + child.price, 0) : scope.row.price }} -->
|
||||
{{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
|
||||
<!-- {{ scope.row.price }} -->
|
||||
{{ proxy.formatPrice(scope.row.price) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="operate" label="操作" align="center">
|
||||
|
@ -41,10 +41,14 @@
|
||||
<el-table-column prop="specification" label="规格" />
|
||||
<el-table-column prop="unit" label="单位" />
|
||||
<el-table-column prop="quantity" label="数量" />
|
||||
<el-table-column prop="unitPrice" label="单价" align="center" />
|
||||
<el-table-column prop="price" label="总价" align="center">
|
||||
<el-table-column prop="unitPrice" label="单价" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
|
||||
{{ proxy.formatPrice(scope.row.unitPrice, false) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="总价" align="center" width="150">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.price) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -70,8 +74,12 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3">
|
||||
<el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">取消</el-button>
|
||||
<el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors">确认</el-button>
|
||||
<el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors"
|
||||
>确认</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
@ -1,34 +1,6 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-tabs type="border-card" v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="变更单" name="1"
|
||||
><el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" :disabled="addSingle" @click="handleAddApp" v-hasPermi="['quality:qualityInspection:add']"
|
||||
>上传变更单模版</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<EngineeringChangeApplicationForm
|
||||
@selection-change="handleSelectionChange"
|
||||
:data="tableData"
|
||||
:thumbnail="projectTypeOptions[1].thumbnail"
|
||||
@delete="handleDelete"
|
||||
></EngineeringChangeApplicationForm>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/> </el-card
|
||||
></el-tab-pane>
|
||||
<el-tab-pane label="外部联系单" name="0"
|
||||
><el-card shadow="never">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
@ -40,15 +12,8 @@
|
||||
</el-row>
|
||||
</template>
|
||||
<Contactform @selection-change="handleSelectionChange" :data="tableData" @delete="handleDelete"></Contactform>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/> </el-card
|
||||
></el-tab-pane>
|
||||
</el-tabs>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<el-dialog title="新增模板" v-model="dialogVisible" width="800">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="110px">
|
||||
<div class="flex">
|
||||
@ -109,14 +74,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import type { FormInstance, FormRules } from 'element-plus';
|
||||
import type { FormInstance } from 'element-plus';
|
||||
import Contactform from './components/contactform.vue';
|
||||
import EngineeringChangeApplicationForm from './components/engineeringChangeApplicationForm.vue';
|
||||
import { listContactTypeformtemplate } from '@/api/cory/contactformtemplate';
|
||||
import { addContactnotice, delContactnotice, listContactnotice } from '@/api/cory/contactnotice';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { wf_business_status } = toRefs(proxy?.useDict('wf_business_status'));
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
|
@ -111,8 +111,7 @@ import { useUserStoreHook } from '@/store/modules/user';
|
||||
import type { FormInstance, FormRules } from 'element-plus';
|
||||
import Notice from './components/notice.vue';
|
||||
import { listContactTypeformtemplate } from '@/api/cory/contactformtemplate';
|
||||
import { addContactnotice, delContactnotice, listContactnotice } from '@/api/cory/contactnotice';
|
||||
import { listProjectTeamForeman } from '@/api/project/projectTeam';
|
||||
import { addContactnotice, delContactnotice, listContactnotice, listProjectTeamForeman } from '@/api/cory/contactnotice';
|
||||
import { foremanQuery, ProjectTeamForemanResp } from '@/api/project/projectTeam/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@ -265,6 +264,7 @@ const getList = async () => {
|
||||
tableData.value = res.rows;
|
||||
total.value = res.total || 0;
|
||||
// 获取项目班组信息
|
||||
console.log('🚀 ~ getList ~ currentProject.value?.id:', currentProject.value?.id);
|
||||
const teamRes = await listProjectTeamForeman(currentProject.value?.id);
|
||||
teamList.value = teamRes.data;
|
||||
teamOpt.value = teamList.value.map((team: ProjectTeamForemanResp) => ({
|
||||
|
@ -14,8 +14,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="合同类型" prop="contractType">
|
||||
<el-select v-model="form.contractType" placeholder="请选择合同类型">
|
||||
<el-option v-for="item in income_contract_type" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
<el-option v-for="item in income_contract_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="业主单位" prop="contractOwner">
|
||||
@ -28,15 +27,17 @@
|
||||
<editor v-model="form.contractedContent" :min-height="192" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同金额" prop="amount">
|
||||
<el-input v-model="form.amount" placeholder="请输入合同金额"
|
||||
oninput="value=value.replace(/[^0-9.]/g,'').replace(/\.{2,}/g,'.').replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')" />
|
||||
<el-input
|
||||
v-model="form.amount"
|
||||
placeholder="请输入合同金额"
|
||||
oninput="value=value.replace(/[^0-9.]/g,'').replace(/\.{2,}/g,'.').replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="附件">
|
||||
<FileUpload :multiple="true" :fileType="['pdf']" :onUploadSuccess="onUploadSuccess"
|
||||
:ref="fileRef" :defaultFileList="tempFileList" />
|
||||
<FileUpload :multiple="true" :fileType="['pdf']" :onUploadSuccess="onUploadSuccess" :ref="fileRef" :defaultFileList="tempFileList" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div>
|
||||
@ -212,11 +213,11 @@ onMounted(async () => {
|
||||
if (id) {
|
||||
const { data } = await getIncomeContract(id);
|
||||
form.value.id = data.id;
|
||||
form.value.contractOwner = data.contractOwner
|
||||
form.value.contractOwner = data.contractOwner;
|
||||
} else {
|
||||
router.push('/ctr/incomeContract');
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
|
@ -145,7 +145,13 @@
|
||||
></el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="费用" prop="costEstimation">
|
||||
<el-input min="0" v-model="form.costEstimation" type="number" placeholder="请输入费用" /> </el-form-item
|
||||
<el-input-number
|
||||
:min="0"
|
||||
:precision="4"
|
||||
v-model="form.costEstimation"
|
||||
:controls="false"
|
||||
placeholder="请输入费用"
|
||||
/> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="变更费用估算表" label-width="110px" prop="costEstimationFile">
|
||||
|
@ -0,0 +1,396 @@
|
||||
<template>
|
||||
<div class="content-box">
|
||||
<el-table :data="data" style="width: 100%" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="index" width="55" label="序号" align="center" />
|
||||
<el-table-column align="center" prop="projectName" label="工程名称" />
|
||||
<el-table-column align="center" prop="submitUnit" label="提出单位" />
|
||||
<el-table-column align="center" prop="specialty" label="专业">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="des_user_major" :value="row.specialty" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="submitDate" label="提出日期">
|
||||
<template #default="{ row }">
|
||||
{{ formatDate(row.submitDate) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="volumeName" label="卷册名称" />
|
||||
<el-table-column align="center" prop="volumeNumber" label="卷册号" />
|
||||
<el-table-column align="center" prop="content" label="变更内容" />
|
||||
<el-table-column align="center" prop="costEstimation" label="变更费用估算" />
|
||||
<el-table-column label="流程状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="wf_business_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="content" label="操作" width="240">
|
||||
<template #default="scope">
|
||||
<el-button link type="warning" v-if="scope.row.status === 'draft'" icon="Edit" @click="handleUpdate(scope.row)" class="ml-3"
|
||||
>审批
|
||||
</el-button>
|
||||
<el-button link type="primary" icon="View" @click="handleViewInfo(scope.row)" class="ml-3"> 查看流程 </el-button>
|
||||
<el-button link type="success" icon="View" @click="handleDetail(scope.row)" class="ml-3"> 详情 </el-button>
|
||||
<!-- <el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)"> 删除 </el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 详情 -->
|
||||
<el-dialog title="变更单详情" v-model="detailVisible" width="1000">
|
||||
<div class="w[850px] ma word-export-wrapper" ref="exportRef">
|
||||
<div class="w80% ma">
|
||||
<h2 style="text-align: center; margin-top: 5px; font-weight: bold">变更单</h2>
|
||||
<el-row>
|
||||
<el-col :span="12">编号:{{ tableDetail.id }}</el-col>
|
||||
</el-row>
|
||||
<el-descriptions :column="2" border style="margin-top: 8px" label-width="160px" size="large">
|
||||
<el-descriptions-item label-align="center" label="工程名称" class-name="zebra"> {{ tableDetail.projectName }} </el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="提出单位" class-name="zebra"> {{ tableDetail.submitUnit }} </el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="专业" label-class-name="white"
|
||||
><dict-tag :options="des_user_major" :value="tableDetail.specialty" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="提出日期" label-class-name="white">
|
||||
{{ dayjs(tableDetail.submitDate).format('YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="卷册名称" class-name="zebra"> {{ tableDetail.volumeName }} </el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="卷册号" class-name="zebra"> {{ tableDetail.volumeNumber }} </el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="附图" :span="2" label-class-name="white">
|
||||
<img :src="item.url" v-for="item in tableDetail.attachmentsImgList" alt="" style="width: 200px; height: auto" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="变更原因" :span="2" class-name="zebra">
|
||||
<el-checkbox-group v-model="tableDetail.changeReasons">
|
||||
<el-checkbox
|
||||
v-for="(item, index) in radioList"
|
||||
:class="index % 2 == 0 ? 'w45%' : ''"
|
||||
:label="item.label"
|
||||
:value="item.label"
|
||||
disabled
|
||||
/>
|
||||
</el-checkbox-group>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="内容" :span="2" label-class-name="white">
|
||||
{{ tableDetail.content }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="附件" :span="2" label-class-name="white">
|
||||
<el-link type="primary" :underline="false" :href="tableDetail.attachmentsList?.url" target="_blank">{{
|
||||
tableDetail.attachmentsList?.originalName
|
||||
}}</el-link>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="变更费用估算" :span="2" class-name="zebra">
|
||||
{{ tableDetail.costEstimation }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions border direction="vertical" size="large">
|
||||
<el-descriptions-item label-align="center" label="施工承包单位" class-name="none"></el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="2" border label-width="160px" size="large">
|
||||
<el-descriptions-item label-align="center" label="项目经理 " label-class-name="white">
|
||||
{{ tableDetail.contractorLeader }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="日期" label-class-name="white">
|
||||
{{ dayjs(tableDetail.contractorDate).format('YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- <el-descriptions border direction="vertical" size="large">
|
||||
<el-descriptions-item label-align="center" label="总承包单位" class-name="none"></el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="2" border label-width="160px" size="large">
|
||||
<el-descriptions-item label-align="center" label="项目技术负责人" label-class-name="white">{{
|
||||
tableDetail.bsupervisorLeader
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="日期" label-class-name="white">
|
||||
{{ dayjs(tableDetail.bsupervisorDate).format('YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions border direction="vertical" size="large">
|
||||
<el-descriptions-item label-align="center" label="设计单位" class-name="none"></el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="2" border label-width="160px" size="large">
|
||||
<el-descriptions-item label-align="center" label="设计代表" label-class-name="white">{{
|
||||
tableDetail.csupervisorLeader
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="日期" label-class-name="white">
|
||||
{{ dayjs(tableDetail.csupervisorDate).format('YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions> -->
|
||||
<el-descriptions border direction="vertical" size="large">
|
||||
<el-descriptions-item label-align="center" label="项目监理单位" class-name="none"></el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<!-- 单独插入整行占用的内容 -->
|
||||
<el-descriptions :column="2" border label-width="160px" size="large">
|
||||
<el-descriptions-item label="总监理工程师" label-align="center" label-class-name="white">
|
||||
{{ tableDetail.supervisorLeader }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="日期" label-align="center" label-class-name="white">
|
||||
{{ dayjs(tableDetail.supervisorDate).format('YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- 一组完整两列 -->
|
||||
<!-- <el-descriptions :column="2" border label-width="160px" size="large">
|
||||
<el-descriptions-item label="监理工程师" label-align="center" label-class-name="white">
|
||||
{{ tableDetail.dsupervisorLeader }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="日期" label-align="center" label-class-name="white">
|
||||
{{ dayjs(tableDetail.supervisorDate).format('YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions> -->
|
||||
<el-descriptions border direction="vertical" size="large">
|
||||
<el-descriptions-item label-align="center" label="建设单位" class-name="none"></el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="2" border label-width="160px" size="large">
|
||||
<!-- <el-descriptions-item label-align="center" label="会签" :span="2" label-class-name="white"> {{ tableDetail.esupervisorLeader }} </el-descriptions-item> -->
|
||||
<el-descriptions-item label-align="center" label="负责人" label-class-name="white">
|
||||
{{ tableDetail.ownerRep }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label-align="center" label="日期" label-class-name="white">
|
||||
{{ dayjs(tableDetail.ownerDate).format('YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div class="dialog-footer">
|
||||
<div class="btn-item" @click="handleDownload">
|
||||
<img src="@/assets/icons/svg/derived.png" />
|
||||
<span>下载</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { listByIds } from '@/api/system/oss';
|
||||
import { dayjs } from 'element-plus';
|
||||
import { saveAs } from 'file-saver';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
thumbnail: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
const tableDetail = ref<any>({ attachmentsImgList: [], attachmentsList: [] });
|
||||
|
||||
const exportRef = ref<HTMLElement>();
|
||||
const radioList = ref([
|
||||
{ value: 0, label: '设计漏项' },
|
||||
{ value: 1, label: '设计改进' },
|
||||
{ value: 2, label: '设计差错' },
|
||||
{ value: 3, label: '接口差错' },
|
||||
{ value: 4, label: '业主要求' },
|
||||
{ value: 5, label: '施工承包商要求' },
|
||||
{ value: 6, label: '外部资料与最终情况不符' },
|
||||
{ value: 7, label: '材料代用及其他' }
|
||||
]);
|
||||
const detailVisible = ref(false);
|
||||
const formatDate = (val: string | Date) => (val ? dayjs(val).format('YYYY-MM-DD') : '');
|
||||
const { des_user_major } = toRefs<any>(proxy?.useDict('des_user_major'));
|
||||
|
||||
const handleDetail = async (row) => {
|
||||
tableDetail.value = { ...row };
|
||||
|
||||
if (row.attachmentsImg) {
|
||||
const res = await listByIds(row.attachmentsImg);
|
||||
tableDetail.value.attachmentsImgList = res.data;
|
||||
}
|
||||
if (row.attachments) {
|
||||
const res = await listByIds(row.attachments);
|
||||
tableDetail.value.attachmentsList = res.data[0];
|
||||
}
|
||||
|
||||
// tableDetail.value = {
|
||||
// ...row,
|
||||
// hasAttachmentList: res.data
|
||||
// };
|
||||
detailVisible.value = true;
|
||||
};
|
||||
/** 多选框选中数据 */
|
||||
const emit = defineEmits(['selection-change', 'delete']);
|
||||
const handleSelectionChange = (selection: any) => {
|
||||
emit('selection-change', selection);
|
||||
};
|
||||
const handleDelete = (row) => {
|
||||
emit('delete', row.id);
|
||||
};
|
||||
const handleUpdate = (row) => {
|
||||
// 添加审批
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.push({
|
||||
path: `/approval/changeContact/indexEdit`,
|
||||
query: {
|
||||
thumbnailUrl: props.thumbnail,
|
||||
row: JSON.stringify(row),
|
||||
id: row.id,
|
||||
type: 'update'
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleViewInfo = (row) => {
|
||||
// 添加审批
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.push({
|
||||
path: `/approval/changeContact/indexEdit`,
|
||||
query: {
|
||||
thumbnailUrl: props.thumbnail,
|
||||
row: JSON.stringify(row),
|
||||
id: row.id,
|
||||
type: 'view'
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleDownload = async () => {
|
||||
const style = `
|
||||
<style>
|
||||
.white { background: #fff !important; }
|
||||
.none { display: none !important; }
|
||||
.zebra { background: #f5f7fa !important; }
|
||||
.el-descriptions__table { table-layout: fixed !important; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #333; padding: 6px; font-size: 14px; }
|
||||
</style>
|
||||
`;
|
||||
|
||||
const el = exportRef.value;
|
||||
if (!el) return;
|
||||
|
||||
// 拷贝 DOM,避免影响原内容
|
||||
const clone = el.cloneNode(true) as HTMLElement;
|
||||
|
||||
// 删除 .dialog-footer
|
||||
const footer = clone.querySelector('.dialog-footer');
|
||||
if (footer) {
|
||||
footer.remove();
|
||||
}
|
||||
|
||||
// 工具函数:图片转成指定宽度的 base64
|
||||
const resizeImageToBase64 = (img: HTMLImageElement, maxWidth = 500) => {
|
||||
return new Promise<string>((resolve) => {
|
||||
const image = new Image();
|
||||
image.crossOrigin = 'anonymous';
|
||||
image.src = img.src;
|
||||
image.onload = () => {
|
||||
const scale = Math.min(1, maxWidth / image.naturalWidth);
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = image.naturalWidth * scale;
|
||||
canvas.height = image.naturalHeight * scale;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx!.drawImage(image, 0, 0, canvas.width, canvas.height);
|
||||
resolve(canvas.toDataURL('image/png'));
|
||||
};
|
||||
image.onerror = () => {
|
||||
resolve(img.src); // 如果加载失败就用原地址
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// 找到所有图片并替换成 base64(顺序执行以避免并发问题)
|
||||
const imgs = Array.from(clone.querySelectorAll('img'));
|
||||
for (let img of imgs) {
|
||||
const base64 = await resizeImageToBase64(img, 200);
|
||||
img.src = base64;
|
||||
}
|
||||
|
||||
// 应用表格的内联样式
|
||||
applyInlineTableStyles(clone);
|
||||
|
||||
// 拼接 HTML
|
||||
const html = `
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
${style}
|
||||
</head>
|
||||
<body>
|
||||
${clone.innerHTML}
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const blob = (window as any).htmlDocx.asBlob(html);
|
||||
saveAs(blob, '变更单.docx');
|
||||
};
|
||||
|
||||
const applyInlineTableStyles = (rootEl: HTMLElement) => {
|
||||
rootEl.querySelectorAll('table').forEach((table) => {
|
||||
table.setAttribute('style', 'width:100%; border-collapse:collapse; table-layout:fixed; border:1px solid #333;');
|
||||
});
|
||||
|
||||
rootEl.querySelectorAll('th, td').forEach((cell) => {
|
||||
cell.setAttribute('style', 'border:1px solid #333; padding:6px; font-size:14px; word-break:break-all;');
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.white) {
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
:deep(.none) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
:deep(.zebra) {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
:deep(.el-descriptions__table) {
|
||||
table-layout: fixed !important;
|
||||
}
|
||||
.word-export-wrapper {
|
||||
table {
|
||||
width: 100% !important;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid #333;
|
||||
padding: 8px;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* 确保不超出 Word 页边距 */
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-descriptions__label {
|
||||
font-weight: bold;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.dialog-footer {
|
||||
height: 100px;
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
position: absolute;
|
||||
top: 14%;
|
||||
right: 6%;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 10px #ddd;
|
||||
text-align: center;
|
||||
padding: 20px 10px;
|
||||
|
||||
.btn-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
img {
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
279
src/views/design/shijibiangeng/index.vue
Normal file
@ -0,0 +1,279 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" :disabled="addSingle" @click="handleAddApp" v-hasPermi="['quality:qualityInspection:add']"
|
||||
>上传设计变更单</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<EngineeringChangeApplicationForm
|
||||
@selection-change="handleSelectionChange"
|
||||
:data="tableData"
|
||||
:thumbnail="projectTypeOptions[1].thumbnail"
|
||||
@delete="handleDelete"
|
||||
></EngineeringChangeApplicationForm>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<el-dialog title="新增模板" v-model="dialogVisible" width="800">
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="110px">
|
||||
<div class="flex">
|
||||
<div><image-preview :src="thumbnailUrl" width="150px"></image-preview></div>
|
||||
<div>
|
||||
<el-form-item label="工程名称" prop="projectName">
|
||||
<el-input v-model="form.projectName" placeholder="请输入工程名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="编号" prop="serialNumber">
|
||||
<el-input v-model="form.serialNumber" placeholder="请输入编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="致" prop="to">
|
||||
<el-input v-model="form.to" placeholder="致:" />
|
||||
</el-form-item>
|
||||
<el-form-item label="主题" prop="subject">
|
||||
<el-input v-model="form.subject" placeholder="请输入主题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="内容" prop="content">
|
||||
<el-input v-model="form.content" type="textarea" :rows="6" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
<el-form-item label="附件" prop="attachments">
|
||||
<file-upload v-model="form.attachments" :limit="1" :file-type="['pdf', 'png', 'jpg', 'jpeg', 'gif', 'bmp']"></file-upload>
|
||||
</el-form-item>
|
||||
<el-divider class="mb-10! mt-10!">施工项目部</el-divider>
|
||||
<el-form-item label="项目负责人" prop="contractorLeader">
|
||||
<el-input v-model="form.contractorLeader" placeholder="请输入负责人姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日期" prop="contractorDate">
|
||||
<el-date-picker v-model="form.contractorDate" type="date" placeholder="选择日期" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-divider class="mb-10! mt-10!">项目监理机构</el-divider>
|
||||
|
||||
<el-form-item label="总监理工程师" prop="supervisorLeader">
|
||||
<el-input v-model="form.supervisorLeader" placeholder="请输入总监理工程师姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日期" prop="supervisorDate">
|
||||
<el-date-picker v-model="form.supervisorDate" type="date" placeholder="选择日期" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-divider class="mb-10! mt-10!">建设单位</el-divider>
|
||||
<el-form-item label="业主代表" prop="ownerRep">
|
||||
<el-input v-model="form.ownerRep" placeholder="请输入业主代表" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日期" prop="ownerDate">
|
||||
<el-date-picker v-model="form.ownerDate" type="date" placeholder="选择日期" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import type { FormInstance, FormRules } from 'element-plus';
|
||||
import EngineeringChangeApplicationForm from './components/engineeringChangeApplicationForm.vue';
|
||||
import { listContactTypeformtemplate } from '@/api/cory/contactformtemplate';
|
||||
import { addContactnotice, delContactnotice, listContactnotice } from '@/api/cory/contactnotice';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { wf_business_status } = toRefs(proxy?.useDict('wf_business_status'));
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const thumbnailUrl = ref('');
|
||||
const tableData = ref([]);
|
||||
const total = ref(0);
|
||||
const activeName = ref('1');
|
||||
const formRef = ref<FormInstance>();
|
||||
const dialogVisible = ref<boolean>(false);
|
||||
const showSearch = ref(true);
|
||||
const multiple = ref<boolean>(true);
|
||||
const addSingle = ref<boolean>(false);
|
||||
const single = ref<boolean>(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
|
||||
const projectTypeOptions = ref<any>([
|
||||
{
|
||||
value: '0',
|
||||
label: '外部联系单'
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
label: '变更单'
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: '通知单'
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: '回复单'
|
||||
},
|
||||
{
|
||||
value: '4',
|
||||
label: '签证单'
|
||||
}
|
||||
]);
|
||||
|
||||
const initFormData = {
|
||||
projectType: '',
|
||||
projectName: '',
|
||||
serialNumber: '',
|
||||
to: '',
|
||||
subject: '',
|
||||
content: '',
|
||||
attachments: '',
|
||||
contractorLeader: '',
|
||||
contractorDate: '',
|
||||
supervisorLeader: '',
|
||||
supervisorDate: '',
|
||||
ownerRep: '',
|
||||
ownerDate: '',
|
||||
unitName: '',
|
||||
profession: '',
|
||||
applyDate: '',
|
||||
bookName: '',
|
||||
bookNo: '',
|
||||
hasAttachment: '',
|
||||
changeReasons: [],
|
||||
changeContent: '',
|
||||
costEstimate: ''
|
||||
};
|
||||
const data = reactive<PageData<any, any>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
projectId: currentProject.value?.id,
|
||||
inspectionType: undefined,
|
||||
inspectionStatus: undefined,
|
||||
teamId: undefined,
|
||||
type: undefined,
|
||||
params: {},
|
||||
// ids: ['1942107830848872449', '1942107931415699457'],
|
||||
projectType: undefined
|
||||
},
|
||||
rules: {
|
||||
projectName: [{ required: true, message: '请输入工程名称', trigger: 'blur' }],
|
||||
projectType: [{ required: true, message: '请选择模板类型', trigger: 'blur' }],
|
||||
serialNumber: [{ required: true, message: '请输入编号', trigger: 'blur' }],
|
||||
to: [{ required: true, message: '请输入接收方', trigger: 'blur' }],
|
||||
subject: [{ required: true, message: '请输入主题', trigger: 'blur' }],
|
||||
content: [{ required: true, message: '请输入内容', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const submitForm = () => {
|
||||
formRef.value?.validate(async (valid) => {
|
||||
if (valid) {
|
||||
let data = {
|
||||
type: queryParams.value.type,
|
||||
projectId: currentProject.value?.id,
|
||||
detail: JSON.stringify(form.value)
|
||||
};
|
||||
console.log('提交表单:', form);
|
||||
const res = await addContactnotice(data);
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('添加成功');
|
||||
dialogVisible.value = false;
|
||||
formRef.value.resetFields();
|
||||
getList();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
|
||||
const getList = async () => {
|
||||
if (!queryParams.value.projectType) {
|
||||
const res = await listContactTypeformtemplate(queryParams.value);
|
||||
projectTypeOptions.value = res.data;
|
||||
queryParams.value.projectType = res.data[1].name;
|
||||
thumbnailUrl.value = res.data[1].thumbnail;
|
||||
queryParams.value.type = res.data[1].id as string;
|
||||
}
|
||||
const res = await listContactnotice(queryParams.value);
|
||||
res.rows = res.rows.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
...JSON.parse(item.detail),
|
||||
status: item.status
|
||||
};
|
||||
});
|
||||
tableData.value = res.rows;
|
||||
console.log('🚀 ~ getList ~ tableData.value:', tableData.value);
|
||||
total.value = res.total || 0;
|
||||
};
|
||||
const handleDelete = async (id?: string) => {
|
||||
const _ids = id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除识别记录编号为"' + _ids + '"的数据项?').finally();
|
||||
const res = await delContactnotice(_ids);
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
getList();
|
||||
}
|
||||
};
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: any) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
const selectType = (value: string) => {
|
||||
queryParams.value.projectType = value;
|
||||
thumbnailUrl.value = projectTypeOptions.value.filter((item) => item.name == value)[0].thumbnail;
|
||||
queryParams.value.type = projectTypeOptions.value.filter((item) => item.name == value)[0].id;
|
||||
getList();
|
||||
};
|
||||
|
||||
const handleClick = (val) => {
|
||||
console.log(val);
|
||||
queryParams.value.projectType = val.props.name;
|
||||
getList();
|
||||
};
|
||||
const handleAddApp = (row) => {
|
||||
// 添加审批
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.push({
|
||||
path: `/approval/changeContact/indexEdit`,
|
||||
query: {
|
||||
thumbnailUrl: projectTypeOptions.value[1].thumbnail,
|
||||
id: projectTypeOptions.value[1].id,
|
||||
row,
|
||||
type: 'add'
|
||||
}
|
||||
});
|
||||
};
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
//监听项目id刷新数据
|
||||
const listeningProject = watch(
|
||||
() => currentProject.value?.id,
|
||||
(nid, oid) => {
|
||||
queryParams.value.projectId = nid;
|
||||
getList();
|
||||
}
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
listeningProject();
|
||||
});
|
||||
</script>
|
@ -10,6 +10,13 @@
|
||||
<el-form-item label="资料名称" prop="documentName">
|
||||
<el-input v-model="queryParams.documentName" placeholder="请输入资料名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否文件上传" prop="isUpload" label-width="110px">
|
||||
<el-select v-model="queryParams.isUpload" placeholder="请选择" clearable @keyup.enter="handleQuery">
|
||||
<el-option value="1" label="是" />
|
||||
<el-option value="0" label="否" />
|
||||
<el-option value="2" label="全部" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['design:volumeCatalog:query']">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery" v-hasPermi="['design:volumeCatalog:query']">重置</el-button>
|
||||
@ -154,14 +161,14 @@
|
||||
<el-form-item v-if="uploadForm.type == '3'" label="蓝图" prop="fileIds">
|
||||
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.fileIds"></file-upload>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="uploadForm.type == '3'" label="通知人">
|
||||
<el-form-item v-if="uploadForm.type == '1'" label="过程图纸" prop="cancellationIds">
|
||||
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.cancellationIds"></file-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="通知人">
|
||||
<el-select multiple filterable clearable v-model="form.userIds" placeholder="请选择通知人">
|
||||
<el-option :value="item.userId" v-for="item in userCoryList" :key="item.userId" :label="item.nickName + '-' + item.phonenumber" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="uploadForm.type == '1'" label="过程图纸" prop="cancellationIds">
|
||||
<file-upload :fileType="['pdf']" :isShowTip="false" :fileSize="100" v-model="uploadForm.cancellationIds"></file-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span style="font-size: 12px; color: #999999">注意:请上传pdf格式文件</span>
|
||||
<div style="display: flex; justify-content: flex-end">
|
||||
@ -360,7 +367,8 @@ const data = reactive({
|
||||
designSubitemId: undefined,
|
||||
volumeNumber: undefined,
|
||||
documentName: undefined,
|
||||
params: {}
|
||||
params: {},
|
||||
isUpload: '2'
|
||||
},
|
||||
rules: {
|
||||
design: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||
@ -585,7 +593,6 @@ const handleUploadSuccess = async (flieList: any, res: any) => {
|
||||
};
|
||||
/** 审核蓝图按钮操作 */
|
||||
const handleAuditLantu = async (row) => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.push({
|
||||
path: `/approval/volumeCatalog/blueprintEdit`,
|
||||
query: {
|
||||
@ -596,7 +603,6 @@ const handleAuditLantu = async (row) => {
|
||||
};
|
||||
/** 查看蓝图按钮操作 */
|
||||
const handleAuditViewLantu = async (row) => {
|
||||
proxy.$tab.closePage(proxy.$route);
|
||||
proxy.$router.push({
|
||||
path: `/approval/volumeCatalog/blueprintEdit`,
|
||||
query: {
|
||||
|
@ -0,0 +1,328 @@
|
||||
<template>
|
||||
<div class="centerPage">
|
||||
<div class="centerPage_map">
|
||||
<div ref="mapRef" class="map-container" style="width: 100%; height: 100%" />
|
||||
</div>
|
||||
<div class="centerPage_bottom">
|
||||
<Title title="风险预警">
|
||||
<img src="@/assets/projectLarge/robot.svg" alt="" height="20px" width="20px" />
|
||||
</Title>
|
||||
<div class="centerPage_bottom_table">
|
||||
<el-table v-loading="loading" :data="tableData" show-overflow-tooltip>
|
||||
<el-table-column label="时间" align="center" prop="date" />
|
||||
<el-table-column label="类型" align="center" prop="riskType">
|
||||
<template #default="scope">
|
||||
{{ safety_inspection_type[scope.row.riskType] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="报警内容" align="center" prop="alarmContent" />
|
||||
<el-table-column label="危险等级" align="center" prop="dangerLevel" />
|
||||
<el-table-column label="来源" align="center" prop="source" />
|
||||
<el-table-column label="警告等级" align="center" prop="alarmLevel">
|
||||
<template #default="scope">
|
||||
{{ risk_level_type[scope.row.alarmLevel] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import * as echarts from 'echarts';
|
||||
import china from '@/assets/china.json';
|
||||
import RevenueContractCard from './RevenueContractCard.vue';
|
||||
import bottomboxconpoent from './bottomboxconpoent.vue';
|
||||
import { totalAmount, projectGis } from '@/api/largeScreen/index'; // 导入projectGis接口
|
||||
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
|
||||
import Title from './title.vue';
|
||||
import { earlyWarning } from '@/api/outputApi';
|
||||
import { useDict } from '@/utils/dict';
|
||||
import { getDicts } from '@/api/system/dict/data';
|
||||
// 地图相关变量
|
||||
const mapRef = ref<HTMLDivElement | null>(null);
|
||||
let myChart: any = null;
|
||||
const projectData = ref<any[]>([]); // 存储项目地理信息数据
|
||||
const loading = ref(false);
|
||||
const tableData = ref([]);
|
||||
const risk_level_type = ref();
|
||||
const safety_inspection_type = ref();
|
||||
// 新增:获取项目地理信息数据
|
||||
const getProjectGisData = async () => {
|
||||
try {
|
||||
const response = await projectGis();
|
||||
if (response.code === 200) {
|
||||
// 过滤掉没有经纬度的项目
|
||||
projectData.value = response.data.filter((item: any) => item.lng !== null && item.lat !== null && item.lng !== '' && item.lat !== '');
|
||||
console.log('项目地理数据:', projectData.value);
|
||||
} else {
|
||||
console.error('项目地理数据请求失败:', response.msg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('项目地理数据调用异常:', error);
|
||||
}
|
||||
};
|
||||
//获取字典
|
||||
const getDictsType = async () => {
|
||||
const res = await getDicts('risk_level_type');
|
||||
if (res.code === 200) {
|
||||
risk_level_type.value = res.data.reduce((acc, item) => {
|
||||
acc[item.dictValue] = item.dictLabel;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
};
|
||||
const getDictsType2 = async () => {
|
||||
const res = await getDicts('safety_inspection_type');
|
||||
if (res.code === 200) {
|
||||
safety_inspection_type.value = res.data.reduce((acc, item) => {
|
||||
acc[item.dictValue] = item.dictLabel;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
};
|
||||
//获取表格数据
|
||||
const getTableList = async () => {
|
||||
const res = await earlyWarning();
|
||||
if (res.code === 200) {
|
||||
tableData.value = res.data;
|
||||
}
|
||||
};
|
||||
|
||||
// 地图resize处理
|
||||
const handleResize = () => {
|
||||
if (myChart) myChart.resize();
|
||||
};
|
||||
|
||||
// 初始化地图(修改为使用接口数据)
|
||||
const initEcharts = () => {
|
||||
if (!mapRef.value || projectData.value.length === 0) {
|
||||
console.error('未找到地图容器或项目数据');
|
||||
return;
|
||||
}
|
||||
|
||||
echarts.registerMap('china', china as any);
|
||||
|
||||
// 从接口数据生成散点数据
|
||||
const scatterData = projectData.value.map((item) => ({
|
||||
name: item.projectName,
|
||||
value: [parseFloat(item.lng), parseFloat(item.lat)], // 转换为数值类型
|
||||
shortName: item.shortName,
|
||||
projectSite: item.projectSite,
|
||||
symbol: 'diamond',
|
||||
itemStyle: { color: '#0166d6' },
|
||||
symbolSize: [20, 20],
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b}', // 显示项目名称
|
||||
position: 'top',
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
backgroundColor: 'rgba(3, 26, 52, 0.7)',
|
||||
padding: [3, 6],
|
||||
borderRadius: 3
|
||||
}
|
||||
}));
|
||||
|
||||
myChart = echarts.init(mapRef.value, null, {
|
||||
renderer: 'canvas',
|
||||
useDirtyRect: false
|
||||
});
|
||||
|
||||
const option: any = {
|
||||
roam: true, // 允许缩放和平移
|
||||
geo: {
|
||||
type: 'map',
|
||||
map: 'china',
|
||||
zoom: 2, // 调整初始缩放级别
|
||||
center: [108.95, 34.27], // 中国中心位置经纬度
|
||||
label: { show: false, color: '#fff' },
|
||||
itemStyle: {
|
||||
areaColor: '#031a34',
|
||||
borderColor: '#1e3a6e',
|
||||
borderWidth: 1
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
backgroundColor: 'rgba(3, 26, 52, 0.8)',
|
||||
borderColor: '#1e3a6e',
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
},
|
||||
formatter: function (params: any) {
|
||||
if (params.data) {
|
||||
// 处理散点数据
|
||||
const data = params.data;
|
||||
return `
|
||||
<div style="font-weight: bold;">${data.name}</div>
|
||||
<div>地点:${data.projectSite}</div>
|
||||
<div>经纬度:${data.value[0].toFixed(6)}, ${data.value[1].toFixed(6)}</div>
|
||||
`;
|
||||
}
|
||||
if (params.seriesType === 'map') {
|
||||
// console.log(params, 111111);
|
||||
return `
|
||||
<div style="font-weight: bold;">${params.name}</div>
|
||||
|
||||
`;
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'map',
|
||||
map: 'china',
|
||||
geoIndex: 0,
|
||||
emphasis: {
|
||||
areaColor: '#fff',
|
||||
label: { show: true, color: '#fff' },
|
||||
itemStyle: { areaColor: '#02417e' }
|
||||
},
|
||||
select: { itemStyle: { areaColor: '#02417e' } },
|
||||
data: [] // 可以留空,或根据需要添加区域数据
|
||||
},
|
||||
{
|
||||
type: 'scatter',
|
||||
coordinateSystem: 'geo',
|
||||
data: scatterData,
|
||||
emphasis: {
|
||||
scale: true, // 鼠标悬停时放大
|
||||
symbolSize: [25, 25]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
myChart.setOption(option);
|
||||
};
|
||||
const risk_level_type1 = ref([]);
|
||||
const safety_inspection_type1 = ref([]);
|
||||
// 组件生命周期
|
||||
onMounted(() => {
|
||||
nextTick(async () => {
|
||||
// 先获取合同数据和项目地理数据,再初始化地图
|
||||
getDictsType();
|
||||
getDictsType2();
|
||||
await Promise.all([getProjectGisData()]);
|
||||
initEcharts();
|
||||
getTableList();
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
if (myChart) {
|
||||
myChart.dispose();
|
||||
myChart = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.centerPage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// justify-content: space-between;
|
||||
padding: 0 10px 10px 10px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.centerPage_map {
|
||||
width: 100%;
|
||||
height: 65vh;
|
||||
}
|
||||
.centerPage_bottom {
|
||||
width: 100%;
|
||||
height: 25vh;
|
||||
border: 1px solid rgba(29, 214, 255, 0.1);
|
||||
padding: 10px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.centerPage_bottom_table {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
:deep(.el-table, .el-table__expanded-cell) {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
:deep(.el-table tr) {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
// border: 1px solid rgba(0, 255, 255, 0.5) !important;
|
||||
}
|
||||
:deep(.el-table .el-table__header-wrapper th, .el-table .el-table__fixed-header-wrapper th) {
|
||||
background: rgba(0, 0, 0, 0) !important;
|
||||
}
|
||||
:deep(.el-table th.el-table__cell) {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
color: #fff;
|
||||
border-bottom: 1px solid transparent !important;
|
||||
border-right: 1px solid transparent !important;
|
||||
}
|
||||
:deep(.el-table--enable-row-transition .el-table__body td.el-table__cell) {
|
||||
border-right: 1px solid transparent !important;
|
||||
border-bottom: 1px solid transparent !important;
|
||||
}
|
||||
|
||||
:deep(.el-table__body tr:hover > td) {
|
||||
background-color: rgba(40, 75, 91, 0.9) !important;
|
||||
}
|
||||
/* 表格边框颜色 */
|
||||
:deep(.el-table, .el-table__header-wrapper, .el-table__body-wrapper, .el-table__footer-wrapper, .el-table th, .el-table td) {
|
||||
border: 1px solid transparent !important;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
:deep(.el-table__inner-wrapper:before) {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
/* 固定列的边框 */
|
||||
:deep(.el-table__fixed, .el-table__fixed-right) {
|
||||
border: 1px solid transparent !important;
|
||||
}
|
||||
:deep(.el-table__body-wrapper::-webkit-scrollbar) {
|
||||
width: 4px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper::-webkit-scrollbar-thumb) {
|
||||
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
opacity: 0.2;
|
||||
background: #00c0ff;
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper::-webkit-scrollbar-track) {
|
||||
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 0;
|
||||
background: rgba(220, 228, 245, 0.8);
|
||||
}
|
||||
|
||||
:deep(.el-icon-arrow-right:before) {
|
||||
color: #0ff;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条优化
|
||||
.centerPage_bottom_table::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.centerPage_bottom_table::-webkit-scrollbar-thumb {
|
||||
background-color: #0ff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.centerPage_bottom_table::-webkit-scrollbar-track {
|
||||
background-color: rgba(0, 255, 255, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="header_left">
|
||||
<div class="header_left_img">
|
||||
<img src="@/assets/large/secure.png" style="width: 100%; height: 100%" />
|
||||
</div>
|
||||
<div style="font-size: 12px; padding-left: 10px">安全生产天数:</div>
|
||||
<div class="header_left_text">
|
||||
{{ safetyDay }}
|
||||
<span style="font-size: 12px">天</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">
|
||||
<div>煤科建管-新能源项目数智化管理平台</div>
|
||||
<div>Coal Science Construction Management - New Energy Project Digital Intelligent Management Platform</div>
|
||||
</div>
|
||||
<div class="header_right">
|
||||
<div class="top-bar">
|
||||
<!-- 左侧:天气图标 + 日期文字 -->
|
||||
<div class="left-section">
|
||||
<div class="weather-list" @mouseenter="requestPause" @mouseleave="resumeScroll">
|
||||
<div
|
||||
v-for="(item, i) in weatherList"
|
||||
:key="i"
|
||||
class="weather-item"
|
||||
:style="{ transform: `translateY(-${offsetY}px)`, transition: transition }"
|
||||
>
|
||||
<img :src="`../../../src/assets/images/${item.icon}.png`" alt="" />
|
||||
<div>{{ item.weather }}{{ item.tempMin }}°/{{ item.tempMax }}°</div>
|
||||
<div>{{ item.week }}({{ item.date }})</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 分割线 -->
|
||||
<div class="divider">
|
||||
<div class="top-block"></div>
|
||||
<div class="bottom-block"></div>
|
||||
</div>
|
||||
<!-- 右侧:管理系统图标 + 文字 -->
|
||||
<div class="right-section">
|
||||
<img src="@/assets/large/setting.png" alt="设置图标" />
|
||||
<span>管理系统</span>
|
||||
</div>
|
||||
<!-- 分割线 -->
|
||||
<div class="divider">
|
||||
<div class="top-block"></div>
|
||||
<div class="bottom-block"></div>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="change" @click="emit('changePage')">
|
||||
<el-icon size="20" v-if="!isFull">
|
||||
<Expand />
|
||||
</el-icon>
|
||||
<el-icon size="20" v-else>
|
||||
<Fold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { getScreenSafetyDay, getScreenWeather } from '@/api/projectScreen';
|
||||
|
||||
interface Weather {
|
||||
week: string;
|
||||
date: string;
|
||||
icon: string;
|
||||
weather: string;
|
||||
tempMax: string;
|
||||
tempMin: string;
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
projectId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isFull: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['changePage']);
|
||||
|
||||
const safetyDay = ref<number>(0);
|
||||
const weatherList = ref<Weather[]>([]);
|
||||
const timer = ref<number | null>(0);
|
||||
const offsetY = ref<number>(0);
|
||||
const curIndex = ref(0);
|
||||
const transition = ref('transform 0.5s ease');
|
||||
const pendingPause = ref(false);
|
||||
|
||||
/**
|
||||
* 判断当前时间是白天/夜晚
|
||||
*/
|
||||
function judgeDayOrNight(sunRise: string, sunSet: string) {
|
||||
// 将 "HH:MM" 格式转为分钟数(便于计算)
|
||||
const timeToMinutes = (timeStr: any) => {
|
||||
const [hours, minutes] = timeStr.split(':').map(Number);
|
||||
return isNaN(hours) || isNaN(minutes) ? 0 : hours * 60 + minutes;
|
||||
};
|
||||
// 转换日出、日落时间为分钟数
|
||||
const sunRiseMinutes = timeToMinutes(sunRise);
|
||||
const sunSetMinutes = timeToMinutes(sunSet);
|
||||
// 获取当前时间并转为分钟数
|
||||
const now = new Date();
|
||||
const currentMinutes = now.getHours() * 60 + now.getMinutes();
|
||||
// true 白天 false 夜晚
|
||||
return currentMinutes >= sunRiseMinutes && currentMinutes <= sunSetMinutes ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置天气周期滑动
|
||||
*/
|
||||
const setWeatherScroll = () => {
|
||||
curIndex.value += 1;
|
||||
transition.value = 'transform 0.3s ease';
|
||||
offsetY.value = curIndex.value * 60;
|
||||
|
||||
if (curIndex.value === weatherList.value.length - 1) {
|
||||
setTimeout(() => {
|
||||
transition.value = 'none';
|
||||
curIndex.value = 0;
|
||||
offsetY.value = 0;
|
||||
}, 350);
|
||||
}
|
||||
};
|
||||
|
||||
function startScroll() {
|
||||
if (timer.value) clearInterval(timer.value);
|
||||
timer.value = window.setInterval(setWeatherScroll, 5000);
|
||||
}
|
||||
|
||||
function requestPause() {
|
||||
if (timer.value) {
|
||||
clearInterval(timer.value);
|
||||
timer.value = null;
|
||||
}
|
||||
pendingPause.value = true;
|
||||
}
|
||||
|
||||
function resumeScroll() {
|
||||
console.log('resumeScroll');
|
||||
pendingPause.value = false;
|
||||
startScroll();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
/**
|
||||
* 获取安全生产天数
|
||||
*/
|
||||
getScreenSafetyDay(props.projectId).then((res) => {
|
||||
const { data, code } = res;
|
||||
if (code === 200) {
|
||||
safetyDay.value = data.safetyDay;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 获取近三天天气
|
||||
*/
|
||||
getScreenWeather(props.projectId).then((res) => {
|
||||
const { data, code } = res;
|
||||
if (code === 200) {
|
||||
data.forEach((item) => {
|
||||
if (judgeDayOrNight(item.sunRise, item.sunSet)) {
|
||||
item.weather = item.dayStatus;
|
||||
item.icon = item.dayIcon;
|
||||
} else {
|
||||
item.weather = item.nightStatus;
|
||||
item.icon = item.nightIcon;
|
||||
}
|
||||
});
|
||||
weatherList.value = data;
|
||||
// 多添加第一项 实现无缝衔接
|
||||
weatherList.value = [...weatherList.value, weatherList.value[0]];
|
||||
startScroll();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer.value) {
|
||||
clearInterval(timer.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.header {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr 1fr;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.header_left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header_left_img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
box-sizing: border-box;
|
||||
// padding-right: 10px;
|
||||
}
|
||||
|
||||
.header_left_text {
|
||||
font-weight: 500;
|
||||
text-shadow: 0px 1.24px 6.21px rgba(25, 179, 250, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.header_right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #fff;
|
||||
font-family: 'AlimamaShuHeiTi', sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title > div:first-child {
|
||||
/* 第一个子元素的样式 */
|
||||
font-size: 38px;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.title > div:last-child {
|
||||
/* 最后一个子元素的样式 */
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 顶部栏容器:Flex 水平布局 + 垂直居中 */
|
||||
.top-bar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
color: #fff;
|
||||
padding: 8px 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 左侧区域(天气 + 日期):自身也用 Flex 水平排列,确保元素在一行 */
|
||||
.left-section {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.weather-list {
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
|
||||
.weather-item {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > div:last-child {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 分割线(视觉分隔,可根据需求调整样式) */
|
||||
.divider {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
gap: 2px;
|
||||
padding: 14px 10px;
|
||||
}
|
||||
|
||||
.divider .top-block {
|
||||
width: 2px;
|
||||
height: 7px;
|
||||
background: #19b5fb;
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.divider .bottom-block {
|
||||
width: 2px;
|
||||
height: 7px;
|
||||
background: #19b5fb;
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
/* 右侧区域(管理系统):图标 + 文字水平排列 */
|
||||
.right-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: 'AlimamaShuHeiTi', sans-serif;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.right-section img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 6px;
|
||||
/* 图标与文字间距 */
|
||||
}
|
||||
|
||||
.change {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,540 @@
|
||||
<template>
|
||||
<div class="leftPage">
|
||||
<div class="topPage">
|
||||
<Title style="font-size: 22px" title="企业关键指标" />
|
||||
<div class="indicators">
|
||||
<div class="indicator-card" v-for="indicator in indicators" :key="indicator.id">
|
||||
<div style="display: flex; align-items: baseline; gap: 4px; margin-bottom: 5px">
|
||||
<div class="indicator-value">{{ indicator.value }}</div>
|
||||
<div class="indicator-unit">{{ indicator.unit }}</div>
|
||||
</div>
|
||||
<div class="indicator-name">{{ indicator.name }}</div>
|
||||
<div class="indicator-icon">
|
||||
<img :src="indicator.iconPath" :alt="indicator.name" v-if="indicator.iconPath" style="width: 50px; height: 50px" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="endPage">
|
||||
<Title style="font-size: 22px" title="人员情况" />
|
||||
<div class="map">
|
||||
<div class="project_attendance_chart">
|
||||
<Title style="font-size: 22px" title="各项目人员出勤率" />
|
||||
<div class="chart_content" ref="attendanceChartRef"></div>
|
||||
</div>
|
||||
<div class="attendance_tag">
|
||||
<div class="tag_item">
|
||||
<img src="@/assets/projectLarge/people.svg" alt="" />
|
||||
<div class="tag_title">出勤人</div>
|
||||
<div class="tag_info">
|
||||
{{ attendanceCount }}
|
||||
<span style="font-size: 14px">人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tag_item">
|
||||
<img src="@/assets/projectLarge/people.svg" alt="" />
|
||||
<div class="tag_title">在岗人</div>
|
||||
<div class="tag_info">
|
||||
{{ peopleCount }}
|
||||
<span style="font-size: 14px">人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tag_item">
|
||||
<img src="@/assets/projectLarge/people.svg" alt="" />
|
||||
<div class="tag_title">出勤率</div>
|
||||
<div class="tag_info">
|
||||
{{ attendanceRate }}
|
||||
<span style="font-size: 14px">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="attendance_tag"></div>
|
||||
</div>
|
||||
|
||||
<!-- 项目出勤率柱状图 -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import Title from './title.vue';
|
||||
import { getScreenNews, getScreenPeople } from '@/api/projectScreen';
|
||||
import { keyIndex } from '@/api/enterpriseLarge/index';
|
||||
import { mapOption } from './optionList';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
const props = defineProps({
|
||||
projectId: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
let mapChart = null;
|
||||
const mapChartRef = ref<HTMLDivElement | null>(null);
|
||||
const indicators = ref([
|
||||
{
|
||||
id: '1',
|
||||
name: '在建项目',
|
||||
value: '28',
|
||||
unit: '个',
|
||||
iconPath: '/src/assets/images/beUnder.png'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '合同总额',
|
||||
value: '288.88',
|
||||
unit: '亿元',
|
||||
iconPath: '/src/assets/images/contract.png'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: '总容量',
|
||||
value: '158.88',
|
||||
unit: '个',
|
||||
iconPath: '/src/assets/images/totalCapacity.png'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
name: '今日施工',
|
||||
value: '18',
|
||||
unit: '个',
|
||||
iconPath: '/src/assets/images/todayConstruction.png'
|
||||
}
|
||||
]);
|
||||
|
||||
const news = ref([]);
|
||||
const newDetail = ref({
|
||||
title: '',
|
||||
content: ''
|
||||
});
|
||||
const newId = ref('');
|
||||
const attendanceCount = ref(0);
|
||||
const attendanceRate = ref(0);
|
||||
const peopleCount = ref(0);
|
||||
const teamAttendanceList = ref([{ id: '', teamName: '', attendanceNumber: 0, allNumber: 0, attendanceRate: 0, attendanceTime: '' }]);
|
||||
|
||||
// 项目出勤率数据
|
||||
const projectAttendanceData = ref([
|
||||
{ name: 'A项目', value: 62 },
|
||||
{ name: 'B项目', value: 56 },
|
||||
{ name: 'C项目', value: 95 },
|
||||
{ name: 'D项目', value: 64 },
|
||||
{ name: 'E项目', value: 97.5 }
|
||||
]);
|
||||
|
||||
let attendanceChart = null;
|
||||
const attendanceChartRef = ref<HTMLDivElement | null>(null);
|
||||
|
||||
/**
|
||||
* 获取项目人员出勤数据
|
||||
*/
|
||||
const getPeopleData = async () => {
|
||||
const res = await getScreenPeople(props.projectId);
|
||||
const { data, code } = res;
|
||||
if (code === 200) {
|
||||
attendanceCount.value = data.attendanceCount;
|
||||
attendanceRate.value = data.attendanceRate;
|
||||
peopleCount.value = data.peopleCount;
|
||||
teamAttendanceList.value = data.teamAttendanceList;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取企业关键指标数据
|
||||
*/
|
||||
const getKeyIndexData = async () => {
|
||||
const res = await keyIndex();
|
||||
const { data, code } = res;
|
||||
if (code === 200) {
|
||||
// 更新指标数据,使用接口返回的指定字段
|
||||
indicators.value[0].value = data.ongoingProject || 0;
|
||||
indicators.value[1].value = data.totalContractAmount || 0;
|
||||
indicators.value[2].value = data.totalCapacity || 0;
|
||||
indicators.value[3].value = data.todayProject || 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化项目出勤率柱状图(美化版)
|
||||
*/
|
||||
const initAttendanceChart = () => {
|
||||
if (!attendanceChartRef.value) {
|
||||
return;
|
||||
}
|
||||
attendanceChart = echarts.init(attendanceChartRef.value);
|
||||
|
||||
const option = {
|
||||
backgroundColor: 'transparent',
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
shadowStyle: {
|
||||
color: 'rgba(29, 214, 255, 0.1)'
|
||||
}
|
||||
},
|
||||
backgroundColor: 'rgba(10, 24, 45, 0.8)',
|
||||
borderColor: 'rgba(29, 214, 255, 0.3)',
|
||||
borderWidth: 1,
|
||||
textStyle: {
|
||||
color: '#e6f7ff'
|
||||
},
|
||||
formatter: (params) => {
|
||||
const data = params[0];
|
||||
return `${data.name}<br/>出勤率: ${data.value}%`;
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
top: 40,
|
||||
right: 30,
|
||||
bottom: 40,
|
||||
left: 30,
|
||||
containLabel: true,
|
||||
backgroundColor: 'rgba(10, 24, 45, 0.1)',
|
||||
borderColor: 'rgba(29, 214, 255, 0.1)',
|
||||
borderWidth: 1
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: projectAttendanceData.value.map((item) => item.name),
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(29, 214, 255, 0.3)'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#e6f7ff',
|
||||
fontSize: 14,
|
||||
interval: 0,
|
||||
fontWeight: 'bold',
|
||||
padding: [10, 0, 0, 0]
|
||||
},
|
||||
axisTick: {
|
||||
show: true,
|
||||
length: 5,
|
||||
lineStyle: {
|
||||
color: 'rgba(29, 214, 255, 0.5)'
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 100,
|
||||
interval: 20,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(29, 214, 255, 0.3)'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#e6f7ff',
|
||||
fontSize: 12,
|
||||
formatter: '{value}%',
|
||||
padding: [0, 10, 0, 0]
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(29, 214, 255, 0.15)',
|
||||
type: 'dashed'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: projectAttendanceData.value.map((item) => item.value),
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: function (params) {
|
||||
// 根据数值动态调整渐变效果
|
||||
const value = params.value;
|
||||
const baseColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: 'rgba(29, 214, 255, 1)' },
|
||||
{ offset: 1, color: 'rgba(10, 120, 200, 0.8)' }
|
||||
]);
|
||||
return baseColor;
|
||||
},
|
||||
borderRadius: [5, 5, 0, 0],
|
||||
borderColor: 'rgba(255, 255, 255, 0.3)',
|
||||
borderWidth: 1
|
||||
},
|
||||
barWidth: '45%',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
color: '#e6f7ff',
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold',
|
||||
formatter: '{c}%',
|
||||
offset: [0, -10]
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: 'rgba(29, 214, 255, 1)' },
|
||||
{ offset: 1, color: 'rgba(10, 120, 200, 1)' }
|
||||
]),
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'rgba(29, 214, 255, 0.5)',
|
||||
borderColor: 'rgba(255, 255, 255, 0.5)'
|
||||
},
|
||||
label: {
|
||||
color: '#ffffff',
|
||||
textShadowBlur: 2,
|
||||
textShadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
},
|
||||
animationDelay: function (idx) {
|
||||
// 动画延迟,使柱子依次出现
|
||||
return idx * 100;
|
||||
}
|
||||
}
|
||||
],
|
||||
// 添加动画效果
|
||||
animationEasing: 'elasticOut',
|
||||
animationDelayUpdate: function (idx) {
|
||||
return idx * 5;
|
||||
},
|
||||
// 添加单位标签
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 10,
|
||||
top: 10,
|
||||
style: {
|
||||
text: '单位: %',
|
||||
fill: '#8ab2ff',
|
||||
fontSize: 12
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
attendanceChart.setOption(option);
|
||||
|
||||
// 添加窗口大小变化时的图表更新
|
||||
const handleResize = () => {
|
||||
if (attendanceChart) {
|
||||
attendanceChart.resize();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
// 清理函数
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*/
|
||||
const initMapChart = () => {
|
||||
if (!mapChartRef.value) {
|
||||
return;
|
||||
}
|
||||
mapChart = echarts.init(mapChartRef.value);
|
||||
mapChart.setOption(mapOption);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// nextTick(() => {
|
||||
// initMapChart();
|
||||
// });
|
||||
getPeopleData();
|
||||
getKeyIndexData();
|
||||
|
||||
// 初始化项目出勤率柱状图
|
||||
setTimeout(() => {
|
||||
initAttendanceChart();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
// if (mapChart) {
|
||||
// mapChart.dispose();
|
||||
// mapChart = null;
|
||||
// }
|
||||
|
||||
if (attendanceChart) {
|
||||
attendanceChart.dispose();
|
||||
attendanceChart = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.leftPage {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.topPage,
|
||||
.endPage {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
border: 1px solid rgba(29, 214, 255, 0.1);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.endPage {
|
||||
flex: 1;
|
||||
margin-top: 23px;
|
||||
}
|
||||
|
||||
.project_attendance_chart {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
border: 1px solid rgba(29, 214, 255, 0.1);
|
||||
box-sizing: border-box;
|
||||
|
||||
.chart_title {
|
||||
font-size: 16px;
|
||||
color: #e6f7ff;
|
||||
margin-bottom: 15px;
|
||||
text-align: left;
|
||||
}
|
||||
.chart_content {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.indicators {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 15px;
|
||||
margin-top: 15px;
|
||||
padding: 0 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.indicator-card {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
background: rgba(10, 24, 45, 0.7);
|
||||
border: 1px solid rgba(29, 214, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.indicator-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, rgba(29, 214, 255, 0.2) 0%, rgba(29, 214, 255, 0.6) 50%, rgba(29, 214, 255, 0.2) 100%);
|
||||
}
|
||||
|
||||
.indicator-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #e6f7ff;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.indicator-unit {
|
||||
font-size: 14px;
|
||||
color: #8ab2ff;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.indicator-name {
|
||||
font-size: 14px;
|
||||
color: #e6f7ff;
|
||||
}
|
||||
|
||||
.indicator-icon {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.indicator-icon img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.map {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.attendance_tag {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 30px;
|
||||
margin-top: 15px;
|
||||
|
||||
.tag_item {
|
||||
width: 28%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border: 1px dashed rgba(29, 214, 255, 0.3);
|
||||
padding: 10px;
|
||||
|
||||
.tag_info {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: rgba(230, 247, 255, 1);
|
||||
text-shadow: 0px 1.24px 6.21px rgba(0, 190, 247, 1);
|
||||
}
|
||||
|
||||
.tag_title {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: rgba(230, 247, 255, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.attendance_list {
|
||||
padding: 0px 30px;
|
||||
font-size: 14px;
|
||||
|
||||
.attendance_item {
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 2fr 2fr 3fr;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.subfont {
|
||||
color: rgba(138, 149, 165, 1);
|
||||
}
|
||||
</style>
|
@ -0,0 +1,216 @@
|
||||
export let pieOption = {
|
||||
// 定义中心文字
|
||||
graphic: [
|
||||
// {
|
||||
// type: 'text',
|
||||
// left: 'center',
|
||||
// top: '40%',
|
||||
// style: {
|
||||
// // 需要从接口替换
|
||||
// text: '70%',
|
||||
// fontSize: 24,
|
||||
// fontWeight: 'bold',
|
||||
// fill: '#fff'
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// type: 'text',
|
||||
// left: 'center',
|
||||
// top: '50%',
|
||||
// style: {
|
||||
// text: '111',
|
||||
// fontSize: 14,
|
||||
// fill: '#fff'
|
||||
// }
|
||||
// }
|
||||
],
|
||||
// legend: {
|
||||
// show: true,
|
||||
// type: 'plain',
|
||||
// bottom: 20,
|
||||
// itemWidth: 12,
|
||||
// itemHeight: 12,
|
||||
// textStyle: {
|
||||
// color: '#fff'
|
||||
// }
|
||||
// },
|
||||
series: {
|
||||
type: 'pie',
|
||||
data: [],
|
||||
radius: [50, 80],
|
||||
center: ['50%', '45%'],
|
||||
// itemStyle: {
|
||||
// borderColor: '#fff',
|
||||
// borderWidth: 1
|
||||
// },
|
||||
label: {
|
||||
alignTo: 'edge',
|
||||
formatter: function (params) {
|
||||
// 只显示前三个数据项
|
||||
return `{name|${params.data.name}}\n{percent|${params.data.completionRate}MW}`;
|
||||
},
|
||||
minMargin: 10,
|
||||
edgeDistance: 20,
|
||||
lineHeight: 15,
|
||||
rich: {
|
||||
name: {
|
||||
fontSize: 12,
|
||||
color: '#fff'
|
||||
},
|
||||
percent: {
|
||||
fontSize: 12,
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
top: 'bottom'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export let barOption = {
|
||||
legend: {
|
||||
icon: 'rect',
|
||||
itemWidth: 12,
|
||||
itemHeight: 12,
|
||||
// 调整文字与图标间距
|
||||
data: ['计划产值', '实际产值'],
|
||||
top: 0,
|
||||
right: 10,
|
||||
bottom: 10,
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
show: true,
|
||||
backgroundColor: '',
|
||||
trigger: 'axis',
|
||||
// formatter: '{b0}:{c0}万元',
|
||||
formatter: (params: any) => {
|
||||
// params 是数组,对应每条柱子
|
||||
return params
|
||||
.map((p: any) => `${p.seriesName}:${Number(p.value).toFixed(2)} 亿元`)
|
||||
|
||||
.join('<br/>');
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
},
|
||||
axisPointer: {
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow',
|
||||
}
|
||||
// borderColor: 'rgba(252, 217, 18, 1)'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
|
||||
axisLabel: {
|
||||
color: '#fff'
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: '单位:亿元',
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: '{value}'
|
||||
},
|
||||
splitLine: {
|
||||
show: false // 不显示分割线
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '12%',
|
||||
top: '15%', // 顶部留一点空间给 legend
|
||||
bottom: '8%',
|
||||
right: '2%'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '计划产值',
|
||||
type: 'bar',
|
||||
data: [],
|
||||
barWidth: '10',
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 1, // 修改y为1表示从底部开始
|
||||
x2: 0,
|
||||
y2: 0, // 修改y2为0表示渐变到顶部
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(255, 209, 92, 0.1)' // 底部透明度0.1
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(255, 209, 92, 1)' // 顶部透明度1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '实际产值',
|
||||
type: 'bar',
|
||||
data: [],
|
||||
barWidth: '10',
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 1, // 从底部开始
|
||||
x2: 0,
|
||||
y2: 0, // 到顶部结束
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(7, 209, 250, 0.1)' // 底部透明度0.1
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(7, 209, 250, 1)' // 顶部透明度1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export let mapOption = {
|
||||
geo: {
|
||||
map: 'ch',
|
||||
roam: true,
|
||||
aspectScale: Math.cos((47 * Math.PI) / 180)
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'graph',
|
||||
coordinateSystem: 'geo',
|
||||
data: [
|
||||
{ name: 'a', value: [7.667821250000001, 46.791734269956265] },
|
||||
{ name: 'b', value: [7.404848750000001, 46.516308805996054] },
|
||||
{ name: 'c', value: [7.376673125000001, 46.24728858538375] },
|
||||
{ name: 'd', value: [8.015320625000001, 46.39460918238572] },
|
||||
{ name: 'e', value: [8.616400625, 46.7020608630855] },
|
||||
{ name: 'f', value: [8.869981250000002, 46.37539345234199] },
|
||||
{ name: 'g', value: [9.546196250000001, 46.58676648282309] },
|
||||
{ name: 'h', value: [9.311399375, 47.182454114178896] },
|
||||
{ name: 'i', value: [9.085994375000002, 47.55395822835779] },
|
||||
{ name: 'j', value: [8.653968125000002, 47.47709530818285] },
|
||||
{ name: 'k', value: [8.203158125000002, 47.44506909144329] }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
@ -0,0 +1,392 @@
|
||||
<template>
|
||||
<div class="leftPage">
|
||||
<div class="topPage">
|
||||
<Title title="项目进度分析" />
|
||||
<div class="progress">
|
||||
<div class="progress_item">
|
||||
<div class="progress_imgBox">
|
||||
<div class="progress_img">
|
||||
<img src="@/assets/large/capacity.png" style="width: 100%; height: 100%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress_text">
|
||||
<div class="progress_text_title">
|
||||
<div>{{ capacityData.gridConnectedCapacity ?? '0' }}</div>
|
||||
<div>MW</div>
|
||||
</div>
|
||||
<div class="content_text">井网总容量</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress_item">
|
||||
<div class="progress_imgBox">
|
||||
<div class="progress_img">
|
||||
<img src="@/assets/large/plan.png" style="width: 100%; height: 100%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress_text">
|
||||
<div class="progress_text_title">
|
||||
<div>{{ capacityData.plannedCapacity ?? '0' }}</div>
|
||||
<div>MW</div>
|
||||
</div>
|
||||
<div class="content_text">计划总容量</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress_item">
|
||||
<div class="progress_imgBox">
|
||||
<div class="progress_img">
|
||||
<img src="@/assets/large/delay.png" style="width: 100%; height: 100%" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress_text">
|
||||
<div class="progress_text_title">
|
||||
<div>{{ capacityData.delayedProjectCount ?? '0' }}</div>
|
||||
<div>个</div>
|
||||
</div>
|
||||
<div class="content_text">延期项目</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="projectItem">
|
||||
<div class="chart_container">
|
||||
<div ref="pieChartRef" class="echart" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="output">
|
||||
<Title title="实际产值与预期产值对比" />
|
||||
<div class="chart_container">
|
||||
<div ref="lineChartRef" class="echart" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
|
||||
import Title from './title.vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { pieOption, barOption } from './optionList';
|
||||
import { projectProgress, outpuProgress } from '@/api/outputApi';
|
||||
const capacityData: any = ref({});
|
||||
const props = defineProps({
|
||||
projectId: {
|
||||
type: String,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
|
||||
const generalize = ref();
|
||||
// 饼图相关
|
||||
const pieChartRef = ref<HTMLDivElement | null>(null);
|
||||
let pieChart: any = null;
|
||||
const totalPercent = ref(0);
|
||||
// 折线图相关
|
||||
const lineChartRef = ref<HTMLDivElement | null>(null);
|
||||
let lineChart: any = null;
|
||||
// 土地数据 折线图
|
||||
const designAreaData = ref([]);
|
||||
const transferAreaData = ref([]);
|
||||
const barNames = ref([]);
|
||||
// // 饼图数据
|
||||
// const pieData = [
|
||||
// { label: 'areaPercentage', name: '厂区', value: 0 },
|
||||
// { label: 'roadPercentage', name: '道路', value: 0 },
|
||||
// { label: 'collectorLinePercentage', name: '集电线路', value: 0 },
|
||||
// { label: 'exportLinePercentage', name: '送出线路', value: 0 },
|
||||
// { label: 'substationPercentage', name: '升压站', value: 0 },
|
||||
// { label: 'boxTransformerPercentage', name: '箱变', value: 0 }
|
||||
// ];
|
||||
|
||||
// 响应窗口大小变化
|
||||
const handleResize = () => {
|
||||
if (pieChart) pieChart.resize();
|
||||
if (lineChart) lineChart.resize();
|
||||
};
|
||||
|
||||
const processedDataList = ref([]);
|
||||
//获取数据
|
||||
const getData = async () => {
|
||||
const res = await projectProgress();
|
||||
if (res.code == 200) {
|
||||
capacityData.value = res.data;
|
||||
// processedDataList.value = res.data.projectProgressDetailList;
|
||||
let totalCapacity = 0;
|
||||
const processedData = res.data.projectProgressDetailList.map((item) => {
|
||||
const capacity = parseInt(item.projectCapacity) || 0;
|
||||
totalCapacity += capacity;
|
||||
return {
|
||||
name: item.projectName,
|
||||
value: capacity,
|
||||
completionRate: item.completionRate
|
||||
};
|
||||
});
|
||||
|
||||
// 计算每个项目的百分比
|
||||
processedData.forEach((item) => {
|
||||
item.percentage = totalCapacity > 0 ? ((item.value / totalCapacity) * 100).toFixed(2) : '0%';
|
||||
});
|
||||
processedDataList.value = processedData;
|
||||
initPieChart();
|
||||
}
|
||||
};
|
||||
// 初始化饼图
|
||||
const initPieChart = () => {
|
||||
if (!pieChartRef.value) {
|
||||
console.error('未找到饼图容器元素');
|
||||
return;
|
||||
}
|
||||
const data = processedDataList.value.map((item: any) => {
|
||||
return {
|
||||
name: item.name,
|
||||
value: item.percentage,
|
||||
completionRate: item.value
|
||||
};
|
||||
});
|
||||
pieOption.series.data = data;
|
||||
|
||||
// pieOption.graphic[0].style.text = totalPercent.value + '%';
|
||||
pieChart = echarts.init(pieChartRef.value, null, {
|
||||
renderer: 'canvas',
|
||||
useDirtyRect: false
|
||||
});
|
||||
pieChart.setOption(pieOption);
|
||||
};
|
||||
//获取产值数据
|
||||
const getOutputData = async () => {
|
||||
const res = await outpuProgress();
|
||||
if (res.code == 200) {
|
||||
designAreaData.value = res.data.map((item: any) => Number(item.planValue));
|
||||
transferAreaData.value = res.data.map((item: any) => Number(item.actualValue));
|
||||
barNames.value = res.data.map((item: any) => item.projectName);
|
||||
initLineChart();
|
||||
}
|
||||
};
|
||||
// 初始化柱状图图
|
||||
const initLineChart = () => {
|
||||
if (!lineChartRef.value) {
|
||||
console.error('未找到柱状图容器元素');
|
||||
return;
|
||||
}
|
||||
console.log(barOption);
|
||||
barOption.xAxis.data = barNames.value;
|
||||
barOption.series[0].data = designAreaData.value;
|
||||
barOption.series[1].data = transferAreaData.value;
|
||||
lineChart = echarts.init(lineChartRef.value, null, {
|
||||
renderer: 'canvas',
|
||||
useDirtyRect: false
|
||||
});
|
||||
lineChart.setOption(barOption);
|
||||
};
|
||||
// /**
|
||||
// * 获取项目土地统计数据
|
||||
// */
|
||||
// const getScreenLandData = async () => {
|
||||
// const res = await getScreenLand(props.projectId);
|
||||
// const { data, code } = res;
|
||||
// if (code === 200) {
|
||||
// designAreaData.value = data.map((item: any) => Number(item.designArea));
|
||||
// transferAreaData.value = data.map((item: any) => Number(item.transferArea));
|
||||
// // initLineChart();
|
||||
// }
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * 获取项目形象进度数据
|
||||
// */
|
||||
// const getScreenImgProcessData = async () => {
|
||||
// const res = await getScreenImgProcess(props.projectId);
|
||||
// const { data, code } = res;
|
||||
// if (code === 200) {
|
||||
// totalPercent.value = data.totalPercentage;
|
||||
// pieData.forEach((item: any) => {
|
||||
// item.value = data[item.label];
|
||||
// });
|
||||
// initPieChart();
|
||||
// }
|
||||
// };
|
||||
|
||||
// /**
|
||||
// * 获取项目概况数据
|
||||
// */
|
||||
// const getScreenGeneralizeData = async () => {
|
||||
// const res = await getScreenGeneralize(props.projectId);
|
||||
// const { data, code } = res;
|
||||
// if (code === 200) {
|
||||
// generalize.value = data;
|
||||
// }
|
||||
// };
|
||||
|
||||
// 组件挂载时初始化图表
|
||||
onMounted(() => {
|
||||
// getScreenLandData();
|
||||
// getScreenImgProcessData();
|
||||
// getScreenGeneralizeData();
|
||||
getData();
|
||||
getOutputData();
|
||||
nextTick(() => {
|
||||
initPieChart();
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
});
|
||||
|
||||
// 组件卸载时清理
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
if (pieChart) {
|
||||
pieChart.dispose();
|
||||
pieChart = null;
|
||||
}
|
||||
if (lineChart) {
|
||||
lineChart.dispose();
|
||||
lineChart = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.leftPage {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.topPage {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 15px 0 0 0;
|
||||
border: 1px solid rgba(29, 214, 255, 0.1);
|
||||
box-sizing: border-box;
|
||||
height: 20%;
|
||||
}
|
||||
}
|
||||
|
||||
// .content {
|
||||
// height: 100px;
|
||||
// margin: 0 15px;
|
||||
// padding: 0 10px;
|
||||
// margin-top: 15px;
|
||||
// box-sizing: border-box;
|
||||
// overflow-y: auto;
|
||||
|
||||
// &::-webkit-scrollbar-track {
|
||||
// background: rgba(204, 204, 204, 0.1);
|
||||
// border-radius: 10px;
|
||||
// }
|
||||
|
||||
// &::-webkit-scrollbar-thumb {
|
||||
// background: rgba(29, 214, 255, 0.78);
|
||||
// border-radius: 10px;
|
||||
// }
|
||||
|
||||
// .content_item {
|
||||
// font-size: 14px;
|
||||
// font-weight: 400;
|
||||
// color: rgba(230, 247, 255, 1);
|
||||
// margin-bottom: 10px;
|
||||
|
||||
// &:last-child {
|
||||
// margin-bottom: 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
.progress {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-gap: 10px;
|
||||
.progress_item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// background: rgba(29, 214, 255, 1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
.progress_imgBox {
|
||||
width: 100%;
|
||||
height: 35%;
|
||||
position: relative;
|
||||
.progress_img {
|
||||
width: 84px;
|
||||
height: 48px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 80%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.progress_text {
|
||||
width: 100%;
|
||||
height: 65%;
|
||||
background: rgba(29, 214, 255, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
padding: 15px 5px 5px 5px;
|
||||
.progress_text_title {
|
||||
width: 100%;
|
||||
// height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
& > div:first-child {
|
||||
// 第一个子元素的样式
|
||||
width: 50%;
|
||||
font-size: 24px;
|
||||
// font-weight: bold;
|
||||
font-family: 'AlimamaShuHeiTi', sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
& > div:last-child {
|
||||
// 最后一个子元素的样式
|
||||
width: 50%;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.content_text {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
color: #c6d1db;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.projectItem {
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
// background: rgba(29, 214, 255, 1);
|
||||
padding: 10px 10px 10px 0;
|
||||
// border: 1px solid rgba(29, 214, 255, 0.1);
|
||||
.chart_container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.echart {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.output {
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
// background: rgba(29, 214, 255, 0.5);
|
||||
padding: 10px 10px 10px 0;
|
||||
border: 1px solid rgba(29, 214, 255, 0.1);
|
||||
|
||||
.chart_container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.echart {
|
||||
height: 90%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="title">
|
||||
<div class="title_icon">
|
||||
<img src="@/assets/projectLarge/section.svg" alt="" />
|
||||
<img src="@/assets/projectLarge/border.svg" alt="" />
|
||||
</div>
|
||||
<div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div>{{ title }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '标题'
|
||||
|
||||
},
|
||||
prefix: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
font-family: 'AlimamaShuHeiTi', sans-serif;
|
||||
|
||||
.title_icon {
|
||||
position: relative;
|
||||
|
||||
& > img:last-child {
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -22,11 +22,10 @@ import leftPage from './components/leftPage.vue';
|
||||
import centerPage from './components/centerPage.vue';
|
||||
import rightPage from './components/rightPage.vue';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
|
||||
const userStore = useUserStoreHook();
|
||||
const projectId = computed(() => userStore.selectedProject.id);
|
||||
const isFull = ref(false)
|
||||
const isHideOther = ref(false)
|
||||
const isFull = ref(false);
|
||||
const isHideOther = ref(false);
|
||||
|
||||
/**
|
||||
* 切换中心页面全屏
|
||||
@ -41,7 +40,7 @@ const handleChangePage = () => {
|
||||
isFull.value = true;
|
||||
isHideOther.value = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
@ -140,9 +140,9 @@ const createEarth = () => {
|
||||
// 加载底图
|
||||
loadBaseMap(earthInstance.viewer);
|
||||
|
||||
// 可以取消注释以下代码来设置初始视角
|
||||
// // 可以取消注释以下代码来设置初始视角
|
||||
// YJ.Global.flyTo(earthInstance, view);
|
||||
// YJ.Global.setDefaultView(earthInstance.viewer, view)
|
||||
// YJ.Global.setDefaultView(earthInstance.viewer, view);
|
||||
|
||||
// 地球创建完成后获取并渲染轨迹数据
|
||||
getTrajectoryData();
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
||||
:leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
|
||||
@ -12,15 +11,25 @@
|
||||
<el-input v-model="queryParams.formalitiesId" placeholder="请输入手续办理清单模板id" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="计划开始时间" prop="planTheStartTime">
|
||||
<el-date-picker clearable v-model="queryParams.planTheStartTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划开始时间" />
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.planTheStartTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划开始时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="head">
|
||||
<el-input v-model="queryParams.head" placeholder="请输入负责人" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实际完成时间" prop="actualCompletionTime">
|
||||
<el-date-picker clearable v-model="queryParams.actualCompletionTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择实际完成时间" />
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.actualCompletionTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择实际完成时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="手续材料" prop="formalitiesUrl">
|
||||
<el-input v-model="queryParams.formalitiesUrl" placeholder="请输入手续材料" clearable @keyup.enter="handleQuery" />
|
||||
@ -38,13 +47,15 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd()"
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:getTree']">新增</el-button>
|
||||
<span style="margin-left: 10px"><el-tooltip class="box-item" effect="dark" content="从原有模板列表选择新增"
|
||||
placement="top">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['formalities:formalitiesAreConsolidated:getTree']"
|
||||
>新增</el-button
|
||||
>
|
||||
<span style="margin-left: 10px"
|
||||
><el-tooltip class="box-item" effect="dark" content="从原有模板列表选择新增" placement="top">
|
||||
<el-icon color="#409efc">
|
||||
<WarningFilled />
|
||||
</el-icon> </el-tooltip></span>
|
||||
</el-icon> </el-tooltip
|
||||
></span>
|
||||
</el-col>
|
||||
<el-col :span="1.5" v-hasPermi="['formalities:listOfFormalities:list']">
|
||||
<el-button type="primary" plain icon="Plus" @click="addTemplate()">新增数据</el-button>
|
||||
@ -71,11 +82,20 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="formalitiesAreConsolidatedList" @selection-change="handleSelectionChange"
|
||||
row-key="id" default-expand-all>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:table-layout="'auto'"
|
||||
:data="formalitiesAreConsolidatedList"
|
||||
@selection-change="handleSelectionChange"
|
||||
row-key="id"
|
||||
default-expand-all
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<!-- <el-table-column label="手续办理清单模板父级" align="center" prop="formalitiesPname" /> -->
|
||||
<el-table-column label="手续办理清单" align="left" prop="formalitiesName" />
|
||||
<el-table-column label="手续办理清单" align="left" prop="formalitiesName">
|
||||
<template #default="scope">
|
||||
{{ scope.row.formalitiesName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划开始时间" align="center" prop="planTheStartTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.planTheStartTime, '{y}-{m}-{d}') }}</span>
|
||||
@ -95,52 +115,58 @@
|
||||
<el-table-column label="办理状态" align="center" prop="processingStatus" />
|
||||
<el-table-column label="手续材料" align="center" prop="formalitiesUrl" width="180">
|
||||
<template #default="scope">
|
||||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
|
||||
|
||||
<div>
|
||||
<el-link type="primary" :underline="false" @click="handlePreview(scope.row)" target="_blank"
|
||||
v-if="scope.row.formalitiesPid">查看</el-link>
|
||||
<div style="display: flex; justify-content: center; align-items: center">
|
||||
<div style="width: 30px">
|
||||
<el-link type="primary" :underline="false" @click="handlePreview(scope.row)" target="_blank" v-if="scope.row.formalitiesPid"
|
||||
>查看</el-link
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<el-badge v-if="scope.row.fileCount" :value="scope.row.fileCount" class="item" type="danger">
|
||||
</el-badge>
|
||||
<div style="width: 5px">
|
||||
<el-badge v-if="scope.row.fileCount" :value="scope.row.fileCount" class="item" type="danger"> </el-badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.formalitiesPid">
|
||||
<el-button link type="primary" icon="Edit" v-if="scope.row.processingStatus != '已完成'"
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
v-if="scope.row.processingStatus != '已完成'"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:edit']">修改</el-button>
|
||||
<el-button link type="primary" icon="Upload" v-if="scope.row.processingStatus != '已完成'"
|
||||
@click="handleUpload(scope.row)">上传</el-button>
|
||||
<el-button link type="primary" icon="EditPen" @click="handleUpdateStatus(scope.row)"
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:edit']">修改状态</el-button>
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button link type="primary" icon="Upload" v-if="scope.row.processingStatus != '已完成'" @click="handleUpload(scope.row)"
|
||||
>上传</el-button
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="EditPen"
|
||||
@click="handleUpdateStatus(scope.row)"
|
||||
v-hasPermi="['formalities:formalitiesAreConsolidated:edit']"
|
||||
>修改状态</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改合规性手续合账对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="formalitiesAreConsolidatedFormRef" :model="form" :rules="rules" label-width="160px">
|
||||
<el-form-item label="计划开始时间" prop="planTheStartTime">
|
||||
<el-date-picker clearable v-model="form.planTheStartTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划开始时间">
|
||||
<el-date-picker clearable v-model="form.planTheStartTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择计划开始时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="计划完成时间" prop="planTheStartTime">
|
||||
<el-date-picker clearable v-model="form.planTheEndTime" type="date" value-format="YYYY-MM-DD"
|
||||
placeholder="请选择计划完成时间">
|
||||
<el-date-picker clearable v-model="form.planTheEndTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择计划完成时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="head">
|
||||
@ -162,8 +188,7 @@
|
||||
<el-table :data="fileList" style="width: 100%" border v-loading="fileLoading">
|
||||
<el-table-column prop="fileName" label="文件" align="center">
|
||||
<template #default="scope">
|
||||
<el-link :key="scope.row.annexUrl" :href="scope.row.annexUrl" target="_blank" type="primary"
|
||||
:underline="false">
|
||||
<el-link :key="scope.row.annexUrl" :href="scope.row.annexUrl" target="_blank" type="primary" :underline="false">
|
||||
{{ scope.row.fileName || '查看文件' }}
|
||||
</el-link>
|
||||
</template>
|
||||
@ -174,8 +199,13 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="fileTotal > 0" :total="fileTotal" v-model:page="fileParams.pageNum"
|
||||
v-model:limit="fileParams.pageSize" @pagination="getFileList" />
|
||||
<pagination
|
||||
v-show="fileTotal > 0"
|
||||
:total="fileTotal"
|
||||
v-model:page="fileParams.pageNum"
|
||||
v-model:limit="fileParams.pageSize"
|
||||
@pagination="getFileList"
|
||||
/>
|
||||
<template #footer>
|
||||
<span>
|
||||
<el-button type="primary" @click="viewVisible = false">关闭</el-button>
|
||||
@ -185,9 +215,18 @@
|
||||
<!-- 上传文件对话框 -->
|
||||
<el-dialog draggable title="上传文件" v-model="fileVisible" width="450">
|
||||
<el-form-item label="上传文件" prop="processingStatus">
|
||||
<file-upload v-model="file" ref="uploadRef" uploadUrl="/formalities/formalitiesAnnex"
|
||||
v-hasPermi="['formalities:formalitiesAnnex:add']" :data="{ formalitiesId: form.id }" :fileType="['pdf']"
|
||||
:auto-upload="false" showFileList method="put" :onUploadSuccess="handleUploadSuccess" />
|
||||
<file-upload
|
||||
v-model="file"
|
||||
ref="uploadRef"
|
||||
uploadUrl="/formalities/formalitiesAnnex"
|
||||
v-hasPermi="['formalities:formalitiesAnnex:add']"
|
||||
:data="{ formalitiesId: form.id }"
|
||||
:fileType="['pdf']"
|
||||
:auto-upload="false"
|
||||
showFileList
|
||||
method="put"
|
||||
:onUploadSuccess="handleUploadSuccess"
|
||||
/>
|
||||
</el-form-item>
|
||||
<template #footer>
|
||||
<span>
|
||||
@ -215,14 +254,18 @@
|
||||
</el-dialog>
|
||||
<el-dialog title="新增合规性手续合账" v-model="templateVisbile" width="450">
|
||||
<el-form-item label="合规性手续模板">
|
||||
<el-cascader v-model="tempValue" :options="tempTreeList" :props="{
|
||||
<el-cascader
|
||||
v-model="tempValue"
|
||||
:options="tempTreeList"
|
||||
:props="{
|
||||
multiple: true,
|
||||
value: 'id',
|
||||
label: 'name',
|
||||
disabled: (node: any) => {
|
||||
return (node.pid == 0 && !node.children.length) || node.status == 1; // 有 parent 的是二级,没有 parent 的是一级,禁用一级
|
||||
}
|
||||
}" />
|
||||
}"
|
||||
/>
|
||||
<div style="margin-left: 10px; display: flex; justify-content: center; align-items: center">
|
||||
<el-tooltip class="box-item" effect="dark" content="列表上已选择得模版不可再选" placement="top">
|
||||
<el-icon>
|
||||
@ -248,8 +291,7 @@
|
||||
<el-option v-for="item in listOfFormalitiesList" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="formalitiesName"
|
||||
:rules="[{ required: true, message: '请输入名称', trigger: 'blur' }]">
|
||||
<el-form-item label="名称" prop="formalitiesName" :rules="[{ required: true, message: '请输入名称', trigger: 'blur' }]">
|
||||
<el-input v-model="formTemplate.formalitiesName" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -6,7 +6,7 @@
|
||||
</div>
|
||||
<div style="font-size: 12px; padding-left: 10px">安全生产天数:</div>
|
||||
<div class="header_left_text">
|
||||
1,235
|
||||
{{ safetyDay }}
|
||||
<span style="font-size: 12px">天</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -16,14 +16,20 @@
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="top-bar">
|
||||
<!-- 左侧:天气图标 + 日期文字 -->
|
||||
<!-- 左侧:天气轮播区域 -->
|
||||
<div class="left-section">
|
||||
<img src="@/assets/large/weather.png" alt="天气图标" />
|
||||
|
||||
<span>
|
||||
<span>多云 9°/18°</span>
|
||||
<span style="padding-left: 20px"> {{ week[date.week] }} ({{ date.ymd }})</span>
|
||||
</span>
|
||||
<div class="weather-list" @mouseenter="requestPause" @mouseleave="resumeScroll">
|
||||
<div
|
||||
v-for="(item, i) in weatherList"
|
||||
:key="i"
|
||||
class="weather-item"
|
||||
:style="{ transform: `translateY(-${offsetY}px)`, transition: transition }"
|
||||
>
|
||||
<img :src="`../../../src/assets/images/${item.icon}.png`" alt="" />
|
||||
<div>{{ item.weather }}{{ item.tempMin }}°/{{ item.tempMax }}°</div>
|
||||
<div>{{ item.week }}({{ item.date }})</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 分割线 -->
|
||||
<div class="divider">
|
||||
@ -41,38 +47,164 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { getSafetyDay, getWeather } from '@/api/largeScreen/index';
|
||||
|
||||
interface WeatherData {
|
||||
date: string;
|
||||
week: string;
|
||||
tempMax: string;
|
||||
tempMin: string;
|
||||
sunRise: string;
|
||||
sunSet: string;
|
||||
dayStatus: string;
|
||||
dayIcon: string;
|
||||
nightStatus: string;
|
||||
nightIcon: string;
|
||||
}
|
||||
|
||||
// 星期映射
|
||||
const week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
||||
// 日期数据
|
||||
const date = ref({
|
||||
ymd: '',
|
||||
hms: '',
|
||||
week: 0
|
||||
});
|
||||
// 安全生产天数
|
||||
const safetyDay = ref('');
|
||||
// 用户存储
|
||||
const userStore = useUserStoreHook();
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
|
||||
// 天气轮播相关变量
|
||||
const weatherList = ref<WeatherData[]>([]);
|
||||
const offsetY = ref<number>(0);
|
||||
const curIndex = ref(0);
|
||||
const transition = ref('transform 0.5s ease');
|
||||
const timer = ref<number | null>(0);
|
||||
const pendingPause = ref(false);
|
||||
|
||||
// 判断当前时间是白天/夜晚
|
||||
function judgeDayOrNight(sunRise: string, sunSet: string) {
|
||||
const timeToMinutes = (timeStr: string) => {
|
||||
const [hours, minutes] = timeStr.split(':').map(Number);
|
||||
return isNaN(hours) || isNaN(minutes) ? 0 : hours * 60 + minutes;
|
||||
};
|
||||
const sunRiseMinutes = timeToMinutes(sunRise);
|
||||
const sunSetMinutes = timeToMinutes(sunSet);
|
||||
const now = new Date();
|
||||
const currentMinutes = now.getHours() * 60 + now.getMinutes();
|
||||
return currentMinutes >= sunRiseMinutes && currentMinutes <= sunSetMinutes;
|
||||
}
|
||||
|
||||
// 天气轮播逻辑:每5秒切换一次
|
||||
const setWeatherScroll = () => {
|
||||
curIndex.value += 1;
|
||||
transition.value = 'transform 0.3s ease';
|
||||
offsetY.value = curIndex.value * 60; // 每个天气项高度60px,需和样式一致
|
||||
|
||||
// 轮播到最后一项时,无缝衔接回第一项
|
||||
if (curIndex.value === weatherList.value.length - 1) {
|
||||
setTimeout(() => {
|
||||
transition.value = 'none';
|
||||
curIndex.value = 0;
|
||||
offsetY.value = 0;
|
||||
}, 350);
|
||||
}
|
||||
};
|
||||
|
||||
// 启动轮播定时器
|
||||
function startScroll() {
|
||||
if (timer.value) clearInterval(timer.value);
|
||||
timer.value = window.setInterval(setWeatherScroll, 5000) as unknown as number;
|
||||
}
|
||||
|
||||
// 鼠标悬浮暂停轮播
|
||||
function requestPause() {
|
||||
if (timer.value) {
|
||||
clearInterval(timer.value);
|
||||
timer.value = null;
|
||||
}
|
||||
pendingPause.value = true;
|
||||
}
|
||||
|
||||
// 鼠标离开恢复轮播
|
||||
function resumeScroll() {
|
||||
pendingPause.value = false;
|
||||
startScroll();
|
||||
}
|
||||
|
||||
// 设置实时时间
|
||||
const setTime = () => {
|
||||
let date1 = new Date();
|
||||
let year: any = date1.getFullYear();
|
||||
let month: any = date1.getMonth() + 1;
|
||||
let day: any = date1.getDate();
|
||||
let hours: any = date1.getHours();
|
||||
if (hours < 10) {
|
||||
hours = '0' + hours;
|
||||
}
|
||||
let minutes: any = date1.getMinutes();
|
||||
if (minutes < 10) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
let seconds: any = date1.getSeconds();
|
||||
if (seconds < 10) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
date.value.ymd = year + '-' + month + '-' + day;
|
||||
date.value.hms = hours + ':' + minutes + ':' + seconds;
|
||||
const date1 = new Date();
|
||||
const year = date1.getFullYear();
|
||||
const month = date1.getMonth() + 1;
|
||||
const day = date1.getDate();
|
||||
const hours = date1.getHours().toString().padStart(2, '0');
|
||||
const minutes = date1.getMinutes().toString().padStart(2, '0');
|
||||
const seconds = date1.getSeconds().toString().padStart(2, '0');
|
||||
|
||||
date.value.ymd = `${year}-${month}-${day}`;
|
||||
date.value.hms = `${hours}:${minutes}:${seconds}`;
|
||||
date.value.week = date1.getDay();
|
||||
};
|
||||
// 添加定时器,每秒更新一次时间
|
||||
const timer = setInterval(setTime, 1000);
|
||||
|
||||
// 获取天气数据
|
||||
const getWeatherData = async () => {
|
||||
try {
|
||||
if (currentProject.value?.id) {
|
||||
const res = await getWeather(currentProject.value.id);
|
||||
if (res.code === 200 && res.data && res.data.length > 0) {
|
||||
weatherList.value = res.data;
|
||||
|
||||
// 处理每一天的天气(白天/夜晚切换图标和状态)
|
||||
weatherList.value.forEach((item) => {
|
||||
const isDay = judgeDayOrNight(item.sunRise, item.sunSet);
|
||||
item.status = isDay ? item.dayStatus : item.nightStatus;
|
||||
item.icon = isDay ? item.dayIcon : item.nightIcon;
|
||||
item.tempRange = `${item.tempMin}°/${item.tempMax}°`;
|
||||
});
|
||||
|
||||
// 复制第一项实现无缝轮播
|
||||
weatherList.value = [...weatherList.value, weatherList.value[0]];
|
||||
startScroll(); // 数据加载后启动轮播
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取天气数据失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取安全生产天数
|
||||
const getSafetyDays = async () => {
|
||||
try {
|
||||
if (currentProject.value?.id) {
|
||||
const res = await getSafetyDay(currentProject.value.id);
|
||||
if (res.code === 200 && res.data) {
|
||||
safetyDay.value = res.data.safetyDay.toString();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取安全生产天数失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 组件挂载时初始化
|
||||
onMounted(() => {
|
||||
setTime(); // 初始化时间
|
||||
getSafetyDays();
|
||||
getWeatherData();
|
||||
// 时间定时器(每秒更新)
|
||||
window.setInterval(setTime, 1000);
|
||||
});
|
||||
|
||||
// 组件卸载时清除定时器
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer);
|
||||
if (timer.value) {
|
||||
clearInterval(timer.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -86,41 +218,47 @@ onUnmounted(() => {
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.header_left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header_left_img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
box-sizing: border-box;
|
||||
// padding-right: 10px;
|
||||
}
|
||||
|
||||
.header_left_text {
|
||||
font-weight: 500;
|
||||
text-shadow: 0px 1.24px 6.21px rgba(25, 179, 250, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.header_right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #fff;
|
||||
font-family: 'AlimamaShuHeiTi', sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title > div:first-child {
|
||||
/* 第一个子元素的样式 */
|
||||
font-size: 38px;
|
||||
// font-weight: 300;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.title > div:last-child {
|
||||
/* 最后一个子元素的样式 */
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.3em; /* 调整这个值来控制间距大小 */
|
||||
}
|
||||
.right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* 顶部栏容器:Flex 水平布局 + 垂直居中 */
|
||||
.top-bar {
|
||||
width: 100%;
|
||||
@ -128,27 +266,44 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
// background-color: #1e2128;
|
||||
color: #fff;
|
||||
padding: 8px 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 左侧区域(天气 + 日期):自身也用 Flex 水平排列,确保元素在一行 */
|
||||
.left-section {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// margin-right: auto; /* 让右侧元素(管理系统)居右 */
|
||||
|
||||
.weather-list {
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
|
||||
.weather-item {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > div:last-child {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.left-section img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 8px; /* 图标与文字间距 */
|
||||
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 分割线(视觉分隔,可根据需求调整样式) */
|
||||
.divider {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
height: 100%; /* 根据需要调整高度 */
|
||||
gap: 2px;
|
||||
padding: 14px 10px;
|
||||
}
|
||||
|
||||
@ -165,16 +320,27 @@ onUnmounted(() => {
|
||||
background: #19b5fb;
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
/* 右侧区域(管理系统):图标 + 文字水平排列 */
|
||||
.right-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: 'AlimamaShuHeiTi', sans-serif;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.right-section img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 6px; /* 图标与文字间距 */
|
||||
margin-right: 6px;
|
||||
/* 图标与文字间距 */
|
||||
}
|
||||
|
||||
.change {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,115 +0,0 @@
|
||||
<template>
|
||||
<el-dialog title="添加机械出入场详情" v-model="visible" width="500px" append-to-body>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="140px">
|
||||
<el-form-item label="出入场" prop="outPut">
|
||||
<el-select v-model="form.type" clearable placeholder="请选择出入场">
|
||||
<el-option v-for="item in machinery_entry_exit_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="检验证编号" prop="checkoutNumber">
|
||||
<el-input v-model="form.checkoutNumber" placeholder="请输入检验证编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="检验单位" prop="checkoutUnit">
|
||||
<el-input v-model="form.checkoutUnit" placeholder="请输入检验单位" />
|
||||
</el-form-item>
|
||||
<el-form-item label="检定日期/有效期" prop="checkoutDate">
|
||||
<el-date-picker clearable v-model="form.checkoutDate" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择检定日期/有效期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="施工类型状态" prop="outPut">
|
||||
<el-select v-model="form.status" clearable placeholder="请选择施工类型状态">
|
||||
<el-option v-for="item in sys_normal_disable" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="入场时间" prop="checkoutDate">
|
||||
<el-date-picker clearable v-model="form.entryTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择入场时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片" prop="picture">
|
||||
<image-upload v-model="form.picture" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="loading" type="primary" @click="submitForm">提 交</el-button>
|
||||
<el-button @click="closeDialog">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { defineExpose, reactive, ref } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { MachineryDetailForm } from '@/api/machinery/machineryDetail/types';
|
||||
import { addMachineryDetail } from '@/api/machinery/machineryDetail';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { machinery_entry_exit_type, sys_normal_disable } = toRefs<any>(proxy?.useDict('machinery_entry_exit_type', 'sys_normal_disable'));
|
||||
|
||||
interface Props {
|
||||
machineryId: string | number;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits(['submit']);
|
||||
const visible = ref<boolean>(false);
|
||||
const loading = ref<boolean>(false);
|
||||
|
||||
// 定义表单数据,注意结构与校验规则需要与接口对应
|
||||
const form = reactive<MachineryDetailForm>({
|
||||
machineryId: props.machineryId,
|
||||
checkoutNumber: '',
|
||||
checkoutUnit: '',
|
||||
checkoutDate: '',
|
||||
status: undefined,
|
||||
type: undefined,
|
||||
entryTime: '',
|
||||
remark: '',
|
||||
picture: ''
|
||||
});
|
||||
|
||||
// 定义校验规则
|
||||
const rules = reactive({
|
||||
checkoutNumber: [{ required: true, message: '请输入检验证编号', trigger: 'blur' }],
|
||||
checkoutUnit: [{ required: true, message: '请输入检验单位', trigger: 'blur' }],
|
||||
checkoutDate: [{ required: true, message: '请选择检定日期', trigger: 'blur' }],
|
||||
entryTime: [{ required: true, message: '请选择进场时间', trigger: 'blur' }]
|
||||
});
|
||||
|
||||
const formRef = ref();
|
||||
const imageValue = ref([]);
|
||||
|
||||
const submitForm = () => {
|
||||
formRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
loading.value = true;
|
||||
try {
|
||||
// 调用接口提交数据
|
||||
await addMachineryDetail({ ...form, machineryId: props.machineryId }).finally(() => (loading.value = false));
|
||||
ElMessage.success('提交成功');
|
||||
emit('submit');
|
||||
closeDialog();
|
||||
} catch (error) {
|
||||
ElMessage.error('提交失败');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const closeDialog = () => {
|
||||
visible.value = false;
|
||||
// 重置表单数据
|
||||
formRef.value.resetFields();
|
||||
};
|
||||
|
||||
// 供外部调用的打开方法
|
||||
const openDialog = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
openDialog
|
||||
});
|
||||
</script>
|
@ -1,206 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table size="small" v-if="machineryDetailList.length !== 0" :data="machineryDetailList">
|
||||
<el-table-column label="出入场" align="center" prop="type">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="machinery_entry_exit_type" :value="scope.row.type" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="检验证编号" align="center" prop="checkoutNumber" />
|
||||
<el-table-column label="检验单位" align="center" prop="checkoutUnit" />
|
||||
<el-table-column label="检定日期/有效期" align="center" prop="checkoutDate" />
|
||||
<el-table-column label="入场时间" align="center" prop="entryTime" />
|
||||
<el-table-column label="图片" align="center">
|
||||
<template #default="scope">
|
||||
<el-image
|
||||
:z-index="9999"
|
||||
:preview-src-list="imgList(scope.row.pictureList)"
|
||||
preview-teleported
|
||||
:src="scope.row.pictureList ? scope.row.pictureList[0].url : ''"
|
||||
class="w20"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-space wrap>
|
||||
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['machinery:machineryDetail:edit']">
|
||||
修改
|
||||
</el-button>
|
||||
</el-space>
|
||||
<el-space wrap>
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['machinery:machineryDetail:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
size="small"
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<el-dialog title="修改机械出入场详情" v-model="dialogRef" width="700px" append-to-body>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="140px">
|
||||
<el-form-item label="出入场" prop="type">
|
||||
<el-select v-model="form.type" clearable placeholder="请选择出入场">
|
||||
<el-option v-for="item in machinery_entry_exit_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="检验证编号" prop="checkoutNumber">
|
||||
<el-input v-model="form.checkoutNumber" placeholder="请输入检验证编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="检验单位" prop="checkoutUnit">
|
||||
<el-input v-model="form.checkoutUnit" placeholder="请输入检验单位" />
|
||||
</el-form-item>
|
||||
<el-form-item label="检定日期/有效期" prop="checkoutDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="form.checkoutDate"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择检定日期/有效期"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="施工类型状态" prop="status">
|
||||
<el-select v-model="form.status" clearable placeholder="请选择施工类型状态">
|
||||
<el-option v-for="item in sys_normal_disable" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="入场时间" prop="checkoutDate">
|
||||
<el-date-picker clearable v-model="form.entryTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择入场时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片" prop="picture">
|
||||
<image-upload v-model="form.picture" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="loading" type="primary" @click="submitForm">提 交</el-button>
|
||||
<el-button @click="closeDialog">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { MachineryDetailForm, MachineryDetailQuery, MachineryDetailVO } from '@/api/machinery/machineryDetail/types';
|
||||
import { delMachineryDetail, getMachineryDetail, listMachineryDetail, updateMachineryDetail } from '@/api/machinery/machineryDetail';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { machinery_entry_exit_type, sys_normal_disable } = toRefs<any>(proxy?.useDict('machinery_entry_exit_type', 'sys_normal_disable'));
|
||||
interface Props {
|
||||
machineryId: string | number;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const formRef = ref();
|
||||
const loading = ref(true);
|
||||
const total = ref<number>(0);
|
||||
const initFormData: MachineryDetailForm = {
|
||||
id: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: undefined,
|
||||
type: undefined,
|
||||
entryTime: undefined,
|
||||
remark: undefined,
|
||||
picture: undefined,
|
||||
machineryId: undefined
|
||||
};
|
||||
const data = reactive<PageData<MachineryDetailForm, MachineryDetailQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: undefined,
|
||||
type: undefined,
|
||||
entryTime: undefined,
|
||||
picture: undefined,
|
||||
machineryId: props.machineryId
|
||||
},
|
||||
rules: {
|
||||
checkoutNumber: [{ required: true, message: '请输入检验证编号', trigger: 'blur' }],
|
||||
checkoutUnit: [{ required: true, message: '请输入检验单位', trigger: 'blur' }],
|
||||
checkoutDate: [{ required: true, message: '请选择检定日期', trigger: 'blur' }],
|
||||
entryTime: [{ required: true, message: '请选择进场时间', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const imgList = computed(() => (list) => {
|
||||
let newList;
|
||||
if (list) {
|
||||
newList = list.map((item) => item.url);
|
||||
} else {
|
||||
newList = [''];
|
||||
}
|
||||
return newList;
|
||||
});
|
||||
|
||||
const machineryDetailList = ref<MachineryDetailVO[]>([]);
|
||||
/** 展开选中数据 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listMachineryDetail(queryParams.value);
|
||||
machineryDetailList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: MachineryDetailVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除机械详情编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delMachineryDetail(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: MachineryDetailVO) => {
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getMachineryDetail(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialogRef.value = true;
|
||||
};
|
||||
|
||||
const dialogRef = ref();
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
formRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
loading.value = true;
|
||||
await updateMachineryDetail(form.value).finally(() => (loading.value = false));
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialogRef.value = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
/** 取消按钮 */
|
||||
const closeDialog = () => {
|
||||
dialogRef.value = false;
|
||||
};
|
||||
onMounted(async () => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
154
src/views/machinery/component/add.vue
Normal file
@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div class="system-busMachinery-add">
|
||||
<!-- 添加或修改机械对话框 -->
|
||||
<el-dialog v-model="isShowDialog" width="600px" :close-on-click-modal="false" :destroy-on-close="true">
|
||||
<template #header>
|
||||
<div v-drag="['.system-busMachinery-add .el-dialog', '.system-busMachinery-add .el-dialog__header']"></div>
|
||||
</template>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="机械名称" prop="machineryName">
|
||||
<el-input v-model="formData.machineryName" placeholder="请输入机械名称" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="12"
|
||||
><el-form-item label="型号" prop="machineryNumber">
|
||||
<el-input v-model="formData.machineryNumber" placeholder="请输入型号" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="12"
|
||||
><el-form-item label="负责人" prop="principal">
|
||||
<el-input v-model="formData.principal" :rows="5" placeholder="请输入负责人" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="24"
|
||||
><el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" :rows="5" type="textarea" placeholder="请输入备注" /> </el-form-item
|
||||
></el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="onSubmit">确 定</el-button>
|
||||
<el-button @click="onCancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { reactive, toRefs, defineComponent, ref, unref, getCurrentInstance } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { addBusMachinery } from '@/api/machinery/machinery';
|
||||
import { BusMachineryEditState } from './model';
|
||||
export default defineComponent({
|
||||
name: 'index',
|
||||
props: {
|
||||
statusOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const formRef = ref<HTMLElement | null>(null);
|
||||
const menuRef = ref();
|
||||
const state = reactive<BusMachineryEditState>({
|
||||
loading: false,
|
||||
isShowDialog: false,
|
||||
formData: {
|
||||
id: undefined,
|
||||
machineryName: undefined,
|
||||
machineryNumber: undefined,
|
||||
projectId: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
number: undefined,
|
||||
entryTime: undefined,
|
||||
principal: undefined,
|
||||
remark: undefined
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
id: [{ required: true, message: '序号不能为空', trigger: 'blur' }],
|
||||
machineryName: [{ required: true, message: '机械名称不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '施工类型状态不能为空', trigger: 'blur' }],
|
||||
principal: [{ required: true, message: '负责人不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
resetForm();
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
const formWrap = unref(formRef) as any;
|
||||
if (!formWrap) return;
|
||||
formWrap.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
state.loading = true;
|
||||
//添加
|
||||
addBusMachinery(state.formData)
|
||||
.then(() => {
|
||||
ElMessage.success('添加成功');
|
||||
closeDialog(); // 关闭弹窗
|
||||
emit('busMachineryList');
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
const resetForm = () => {
|
||||
state.formData = {
|
||||
id: undefined,
|
||||
machineryName: undefined,
|
||||
machineryNumber: undefined,
|
||||
projectId: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
entryTime: undefined,
|
||||
principal: undefined,
|
||||
remark: undefined
|
||||
};
|
||||
};
|
||||
return {
|
||||
proxy,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
menuRef,
|
||||
formRef,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.el-col {
|
||||
margin: 10px 0 !important;
|
||||
}
|
||||
</style>
|
156
src/views/machinery/component/detail.vue
Normal file
@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<!-- 机械详情抽屉 -->
|
||||
<div class="system-busMachinery-detail">
|
||||
<el-drawer v-model="isShowDialog" class="busMachinery_detail" size="30%" direction="ltr">
|
||||
<template #header>
|
||||
<h4>机械详情</h4>
|
||||
</template>
|
||||
<el-form ref="formRef" :model="formData" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="机械名称">{{ formData.machineryName }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="型号">{{ formData.machineryNumber }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="数量">{{ formData.ct }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="负责人">{{ formData.principal }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="备注">{{ formData.remark }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建者">{{ formData.createBy }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建时间">{{ formData.createdAt }}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { reactive, toRefs, defineComponent, ref, getCurrentInstance } from 'vue';
|
||||
import { getBusMachinery } from '@/api/machinery/machinery';
|
||||
import { ElLoading } from 'element-plus';
|
||||
import { BusMachineryInfoData, BusMachineryEditState } from './model';
|
||||
export default defineComponent({
|
||||
name: 'index',
|
||||
props: {
|
||||
statusOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const formRef = ref<HTMLElement | null>(null);
|
||||
const menuRef = ref();
|
||||
const state = reactive<BusMachineryEditState>({
|
||||
loading: false,
|
||||
isShowDialog: false,
|
||||
formData: {
|
||||
id: undefined,
|
||||
machineryName: undefined,
|
||||
machineryNumber: undefined,
|
||||
projectId: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
ct: undefined
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
id: [{ required: true, message: '序号不能为空', trigger: 'blur' }],
|
||||
machineryName: [{ required: true, message: '机械名称不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '施工类型状态不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row?: BusMachineryInfoData) => {
|
||||
resetForm();
|
||||
if (row) {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '正在加载中……',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
target: '.busMachinery_detail'
|
||||
});
|
||||
getBusMachinery(row.id!).then((res: any) => {
|
||||
loading.close();
|
||||
const data = res.data;
|
||||
state.formData = data;
|
||||
});
|
||||
}
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
const resetForm = () => {
|
||||
state.formData = {
|
||||
id: undefined,
|
||||
machineryName: undefined,
|
||||
machineryNumber: undefined,
|
||||
projectId: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
ct: undefined
|
||||
};
|
||||
};
|
||||
return {
|
||||
proxy,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
menuRef,
|
||||
formRef,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.system-busMachinery-detail :deep(.el-form-item--large .el-form-item__label) {
|
||||
font-weight: bolder;
|
||||
}
|
||||
.pic-block {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.file-block {
|
||||
width: 100%;
|
||||
border: 1px solid var(--el-border-color);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
margin-bottom: 5px;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
.ml-2 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
184
src/views/machinery/component/edit.vue
Normal file
@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div class="system-busMachinery-edit">
|
||||
<!-- 添加或修改机械对话框 -->
|
||||
<el-dialog v-model="isShowDialog" width="600px" :close-on-click-modal="false" :destroy-on-close="true" custom-class="busMachinery_edit">
|
||||
<template #header>
|
||||
<div v-drag="['.system-busMachinery-edit .el-dialog', '.system-busMachinery-edit .el-dialog__header']">
|
||||
{{ (!formData.id || formData.id == 0 ? '添加' : '修改') + '机械' }}
|
||||
</div>
|
||||
</template>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="110px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="机械名称" prop="machineryName">
|
||||
<el-input v-model="formData.machineryName" placeholder="请输入机械名称" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="12"
|
||||
><el-form-item label="型号" prop="machineryNumber">
|
||||
<el-input v-model="formData.machineryNumber" placeholder="请输入型号" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="12"
|
||||
><el-form-item label="负责人" prop="principal">
|
||||
<el-input v-model="formData.principal" :rows="5" placeholder="请输入负责人" /> </el-form-item
|
||||
></el-col>
|
||||
<el-col :span="24"
|
||||
><el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" :rows="5" type="textarea" placeholder="请输入备注" /> </el-form-item
|
||||
></el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="onSubmit">确 定</el-button>
|
||||
<el-button @click="onCancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { reactive, toRefs, defineComponent, ref, unref, getCurrentInstance } from 'vue';
|
||||
import { ElMessage, ElLoading } from 'element-plus';
|
||||
import { getBusMachinery, addBusMachinery, updateBusMachinery } from '@/api/machinery/machinery';
|
||||
import { BusMachineryInfoData, BusMachineryEditState } from './model';
|
||||
export default defineComponent({
|
||||
name: 'index',
|
||||
props: {
|
||||
statusOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const formRef = ref<HTMLElement | null>(null);
|
||||
const menuRef = ref();
|
||||
const state = reactive<BusMachineryEditState>({
|
||||
loading: false,
|
||||
isShowDialog: false,
|
||||
formData: {
|
||||
id: undefined,
|
||||
machineryName: undefined,
|
||||
machineryNumber: undefined,
|
||||
projectId: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
entryTime: undefined,
|
||||
principal: undefined,
|
||||
remark: undefined
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
id: [{ required: true, message: '序号不能为空', trigger: 'blur' }],
|
||||
machineryName: [{ required: true, message: '机械名称不能为空', trigger: 'blur' }],
|
||||
principal: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '施工类型状态不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row?: BusMachineryInfoData) => {
|
||||
resetForm();
|
||||
if (row) {
|
||||
nextTick(() => {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '正在加载中……',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
target: '.busMachinery_edit'
|
||||
});
|
||||
getBusMachinery(row.id!).then((res: any) => {
|
||||
loading.close();
|
||||
const data = res.data;
|
||||
data.status = '' + data.status;
|
||||
state.formData = data;
|
||||
});
|
||||
});
|
||||
}
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
// 提交
|
||||
const onSubmit = () => {
|
||||
const formWrap = unref(formRef) as any;
|
||||
if (!formWrap) return;
|
||||
formWrap.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
state.loading = true;
|
||||
if (!state.formData.id || state.formData.id === 0) {
|
||||
//添加
|
||||
addBusMachinery(state.formData)
|
||||
.then(() => {
|
||||
ElMessage.success('添加成功');
|
||||
closeDialog(); // 关闭弹窗
|
||||
emit('busMachineryList');
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
} else {
|
||||
//修改
|
||||
updateBusMachinery(state.formData)
|
||||
.then(() => {
|
||||
ElMessage.success('修改成功');
|
||||
closeDialog(); // 关闭弹窗
|
||||
emit('busMachineryList');
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
const resetForm = () => {
|
||||
state.formData = {
|
||||
id: undefined,
|
||||
machineryName: undefined,
|
||||
machineryNumber: undefined,
|
||||
projectId: undefined,
|
||||
checkoutNumber: undefined,
|
||||
checkoutUnit: undefined,
|
||||
checkoutDate: undefined,
|
||||
status: false,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined,
|
||||
deletedAt: undefined,
|
||||
entryTime: undefined,
|
||||
principal: undefined,
|
||||
remark: undefined
|
||||
};
|
||||
};
|
||||
return {
|
||||
proxy,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
menuRef,
|
||||
formRef,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-col {
|
||||
margin: 10px 0 !important;
|
||||
}
|
||||
</style>
|
59
src/views/machinery/component/model.ts
Normal file
@ -0,0 +1,59 @@
|
||||
export interface BusMachineryTableColumns {
|
||||
id:number; // 序号
|
||||
machineryName:string; // 机械名称
|
||||
machineryNumber:string; // 编号
|
||||
checkoutNumber:string; // 检验证编号
|
||||
checkoutUnit:string; // 检验单位
|
||||
checkoutDate:string; // 检定日期/有效期
|
||||
status:string; // 施工类型状态
|
||||
createdAt:string; // 创建时间
|
||||
}
|
||||
|
||||
|
||||
export interface BusMachineryInfoData {
|
||||
id:number|undefined; // 序号
|
||||
machineryName:string|undefined; // 机械名称
|
||||
machineryNumber:string|undefined; // 编号
|
||||
projectId:number|undefined; // 项目id
|
||||
checkoutNumber:string|undefined; // 检验证编号
|
||||
checkoutUnit:string|undefined; // 检验单位
|
||||
checkoutDate:string|undefined; // 检定日期/有效期
|
||||
status:boolean; // 施工类型状态
|
||||
createBy:string|undefined; // 创建者
|
||||
updateBy:string|undefined; // 更新者
|
||||
createdAt:string|undefined; // 创建时间
|
||||
updatedAt:string|undefined; // 更新时间
|
||||
deletedAt:string|undefined; // 删除时间
|
||||
number:number|undefined; //数量
|
||||
entryTime: string|undefined; // 进场时间
|
||||
principal: string|undefined; // 负责人
|
||||
remark: string|undefined; // 备注
|
||||
}
|
||||
|
||||
|
||||
export interface BusMachineryTableDataState {
|
||||
ids:any[];
|
||||
tableData: {
|
||||
data: Array<BusMachineryTableColumns>;
|
||||
total: number;
|
||||
loading: boolean;
|
||||
param: {
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
id: number|undefined;
|
||||
machineryName: string|undefined;
|
||||
status: string|undefined;
|
||||
createdAt: string|undefined;
|
||||
dateRange: string[];
|
||||
projectId: undefined,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export interface BusMachineryEditState{
|
||||
loading:boolean;
|
||||
isShowDialog: boolean;
|
||||
formData:BusMachineryInfoData;
|
||||
rules: object;
|
||||
}
|
@ -1,295 +1,532 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<div class="system-busMachinery-container">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<div class="system-busMachinery-search mb15">
|
||||
<el-form :model="tableData.param" ref="queryRef" :inline="true" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="5" class="colBlock">
|
||||
<el-form-item label="机械名称" prop="machineryName">
|
||||
<el-input v-model="queryParams.machineryName" placeholder="请输入机械名称" clearable @keyup.enter="handleQuery" />
|
||||
<el-input v-model="tableData.param.machineryName" placeholder="请输入机械名称" clearable @keyup.enter="busMachineryList" />
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="principal">
|
||||
<el-input v-model="queryParams.principal" placeholder="请输入负责人" clearable @keyup.enter="handleQuery" />
|
||||
</el-col>
|
||||
<!-- <el-col :span="5">
|
||||
<el-form-item label="施工类型状态" prop="status">
|
||||
<el-select v-model="tableData.param.status" placeholder="请选择施工类型状态" clearable>
|
||||
<el-option v-for="dict in account_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col> -->
|
||||
<!-- <el-col :span="5">
|
||||
<el-form-item label="创建时间" prop="createdAt">
|
||||
<el-date-picker
|
||||
clearable
|
||||
style="width: 200px"
|
||||
v-model="tableData.param.createdAt"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="datetime"
|
||||
placeholder="选择创建时间"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col> -->
|
||||
<el-col :span="6">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" @click="busMachineryList"
|
||||
><el-icon><Search /></el-icon>搜索</el-button
|
||||
>
|
||||
<el-button @click="resetQuery(queryRef)"
|
||||
><el-icon><Refresh /></el-icon>重置</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['machinery:machinery:add']"> 新增 </el-button>
|
||||
<el-button type="primary" @click="handleAdd" v-auth="'api/v1/system/busMachinery/add'"
|
||||
><el-icon><Plus /></el-icon>新增</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['machinery:machinery:edit']">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button type="success" :disabled="single" @click="handleUpdate(null)" v-auth="'api/v1/system/busMachinery/edit'"
|
||||
><el-icon><Edit /></el-icon>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['machinery:machinery:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
<el-button type="danger" :disabled="multiple" @click="handleDelete(null)" v-auth="'api/v1/system/busMachinery/delete'"
|
||||
><el-icon><Delete /></el-icon>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['machinery:machinery:export']">导出 </el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="machineryList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="expand">
|
||||
<template #default="{ row }">
|
||||
<machinery-detail-table :machinery-id="row.id" />
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData.data"
|
||||
@selection-change="handleSelectionChange"
|
||||
:expand-row-keys="expandKeys"
|
||||
:row-key="getRowKeys"
|
||||
@expand-change="expandChange"
|
||||
>
|
||||
<el-table-column type="expand" width="80vw">
|
||||
<template #default="props">
|
||||
<el-table :data="props.row.children.data" v-loading="props.row.children.loading">
|
||||
<el-table-column
|
||||
prop="checkoutNumber"
|
||||
label="合格证编号"
|
||||
align="center"
|
||||
:filters="props.row.children.filterOptions"
|
||||
:filter-method="filterHandler"
|
||||
></el-table-column>
|
||||
<el-table-column prop="checkoutUnit" label="生产厂家" align="center"> </el-table-column>
|
||||
<el-table-column prop="checkoutDate" label="生产日期/有效期" align="center"></el-table-column>
|
||||
<el-table-column prop="type" label="出入场" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.type == 1 ? '出场' : scope.row.type == 2 ? '入场' : '' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="机械名称" align="center" prop="machineryName" />
|
||||
<el-table-column label="机械型号" align="center" prop="machineryNumber" />
|
||||
<el-table-column label="数量" align="center" prop="number" />
|
||||
<el-table-column label="负责人" align="center" prop="principal" />
|
||||
<el-table-column label="负责人电话" align="center" prop="principalPhone" />
|
||||
<el-table-column label="供应商" align="center" prop="provider" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding" width="300">
|
||||
<el-table-column prop="status" label="施工类型状态" :formatter="statusFormat" align="center"> </el-table-column>
|
||||
<el-table-column prop="entryTime" label="入场时间" align="center"></el-table-column>
|
||||
<el-table-column prop="remark" label="备注" align="center" width="200px"> </el-table-column>
|
||||
<el-table-column prop="picture" label="图片" align="center" width="220px">
|
||||
<template #default="scope">
|
||||
<el-space wrap>
|
||||
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['machinery:machinery:edit']">修改 </el-button>
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['machinery:machinery:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
<el-button link type="primary" icon="Plus" @click="handleAddMachineryDetail(scope.row)"> 入场</el-button>
|
||||
</el-space>
|
||||
<div style="display: flex; justify-content: center">
|
||||
<span v-if="scope.row.picture.length" v-for="item in scope.row.picture">
|
||||
<el-image
|
||||
style="width: 100px; height: 50px"
|
||||
v-if="item"
|
||||
:src="'http://58.17.134.85:8920' + item"
|
||||
fit="contain"
|
||||
:zoom-rate="1.2"
|
||||
:preview-src-list="['http://58.17.134.85:8920' + item]"
|
||||
preview-teleported="true"
|
||||
></el-image>
|
||||
</span>
|
||||
<span v-else>暂无图片</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="200px">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="childView(scope.row)"
|
||||
><el-icon><View /></el-icon>详情</el-button
|
||||
>
|
||||
<el-button type="success" link @click="childUpdate(props.row, scope.row)"
|
||||
><el-icon><EditPen /></el-icon>修改</el-button
|
||||
>
|
||||
<el-button type="danger" link @click="childDelete(props.row, scope.row)"
|
||||
><el-icon><DeleteFilled /></el-icon>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<pagination
|
||||
v-show="props.row.children.total > 0"
|
||||
:total="props.row.children.total"
|
||||
v-model:page="childrenData.param.pageNum"
|
||||
v-model:limit="childrenData.param.pageSize"
|
||||
@pagination="busMachineryDetailList(props.row.children, props.row.id)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="序号" align="center" type="index" :index="indexMethod" width="60" />
|
||||
<el-table-column label="机械名称" align="center" prop="machineryName" min-width="100px" />
|
||||
<el-table-column label="型号" align="center" prop="machineryNumber" min-width="100px" />
|
||||
<el-table-column label="数量" align="center" prop="ct" min-width="50px" />
|
||||
<el-table-column label="负责人" align="center" prop="principal" min-width="100px" />
|
||||
<el-table-column label="备注" align="center" prop="remark" min-width="100px" />
|
||||
<el-table-column label="创建时间" align="center" prop="createdAt" min-width="150px">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.createdAt }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding" min-width="250px" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="handleView(scope.row)" v-auth="'api/v1/system/busMachinery/get'"
|
||||
><el-icon><View /></el-icon>详情</el-button
|
||||
>
|
||||
<el-button type="success" link @click="handleUpdate(scope.row)" v-auth="'api/v1/system/busMachinery/edit'"
|
||||
><el-icon><EditPen /></el-icon>修改</el-button
|
||||
>
|
||||
<el-button type="danger" link @click="handleDelete(scope.row)" v-auth="'api/v1/system/busMachinery/delete'"
|
||||
><el-icon><DeleteFilled /></el-icon>删除</el-button
|
||||
>
|
||||
<el-button type="primary" link @click="handleaddChild(scope.row)"
|
||||
><el-icon><Plus /></el-icon>入场</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="tableData.total > 0"
|
||||
:total="tableData.total"
|
||||
v-model:page="tableData.param.pageNum"
|
||||
v-model:limit="tableData.param.pageSize"
|
||||
@pagination="busMachineryList"
|
||||
/>
|
||||
</el-card>
|
||||
<!-- 添加或修改机械对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="machineryFormRef" :model="form" :rules="rules" label-width="90px">
|
||||
<el-form-item label="机械名称" prop="machineryName">
|
||||
<el-input v-model="form.machineryName" placeholder="请输入机械名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="机械型号" prop="machineryNumber">
|
||||
<el-input v-model="form.machineryNumber" placeholder="请输入机械型号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="数量" prop="number">
|
||||
<el-input v-model="form.number" placeholder="请输入数量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="principal">
|
||||
<el-input v-model="form.principal" placeholder="请输入负责人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人电话" prop="principalPhone">
|
||||
<el-input v-model="form.principalPhone" placeholder="请输入负责人电话" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="供应商" prop="provider">
|
||||
<el-input v-model="form.provider" placeholder="请输入供应商" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<machinery-detail-add-dialog :machinery-id="currentMachineryId" ref="dialogRef" @submit="getList" />
|
||||
<apiV1SystemBusMachineryAdd ref="addRef" :statusOptions="account_status" @busMachineryList="busMachineryList"></apiV1SystemBusMachineryAdd>
|
||||
<apiV1SystemBusMachineryEdit ref="editRef" :statusOptions="account_status" @busMachineryList="busMachineryList"></apiV1SystemBusMachineryEdit>
|
||||
<apiV1SystemBusMachineryDetail
|
||||
ref="detailRef"
|
||||
:statusOptions="account_status"
|
||||
@busMachineryList="busMachineryList"
|
||||
></apiV1SystemBusMachineryDetail>
|
||||
<addMachineChild
|
||||
ref="addChildRef"
|
||||
:typeOptions="typeOption"
|
||||
:statusOptions="account_status"
|
||||
@busMachineryDetailList="busMachineryDetailList"
|
||||
></addMachineChild>
|
||||
<editMachineChild
|
||||
ref="editChildRef"
|
||||
:typeOptions="typeOption"
|
||||
:statusOptions="account_status"
|
||||
@busMachineryDetailList="busMachineryDetailList"
|
||||
></editMachineChild>
|
||||
<detailMachineChild
|
||||
ref="deatilChildRef"
|
||||
:typeOptions="typeOption"
|
||||
:statusOptions="account_status"
|
||||
@busMachineryDetailList="busMachineryDetailList"
|
||||
></detailMachineChild>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted, ref, defineComponent, computed, getCurrentInstance, toRaw } from 'vue';
|
||||
import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
|
||||
import { listBusMachinery, delBusMachinery } from '@/api/machinery/machinery';
|
||||
import { BusMachineryTableColumns, BusMachineryInfoData, BusMachineryTableDataState } from './component/model';
|
||||
import apiV1SystemBusMachineryAdd from './component/add.vue';
|
||||
import apiV1SystemBusMachineryEdit from './component/edit.vue';
|
||||
import apiV1SystemBusMachineryDetail from './component/detail.vue';
|
||||
import addMachineChild from '@/views/busMachineryDetail/list/component/add.vue';
|
||||
import editMachineChild from '@/views/busMachineryDetail/list/component/edit.vue';
|
||||
import detailMachineChild from '@/views/busMachineryDetail/list/component/detail.vue';
|
||||
|
||||
<script setup name="Machinery" lang="ts">
|
||||
import { addMachinery, delMachinery, getMachinery, listMachinery, updateMachinery } from '@/api/machinery/machinery';
|
||||
import { MachineryForm, MachineryQuery, MachineryVO } from '@/api/machinery/machinery/types';
|
||||
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import MachineryDetailTable from '@/views/machinery/component/MachineryDetailTable.vue';
|
||||
import MachineryDetailAddDialog from '@/views/machinery/component/MachineryDetailAddDialog.vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const machineryList = ref<MachineryVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const machineryFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: MachineryForm = {
|
||||
id: undefined,
|
||||
machineryName: undefined,
|
||||
machineryNumber: undefined,
|
||||
projectId: currentProject.value?.id,
|
||||
number: undefined,
|
||||
principal: undefined,
|
||||
remark: undefined,
|
||||
principalPhone: undefined,
|
||||
provider: undefined
|
||||
};
|
||||
const data = reactive<PageData<MachineryForm, MachineryQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
machineryName: undefined,
|
||||
machineryNumber: undefined,
|
||||
projectId: currentProject.value?.id,
|
||||
number: undefined,
|
||||
principal: undefined,
|
||||
params: {},
|
||||
principalPhone: undefined,
|
||||
provider: undefined
|
||||
import { listBusMachineryDetail, delBusMachineryDetail } from '@/api/machinery/machineryDetail';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
export default defineComponent({
|
||||
name: 'index',
|
||||
components: {
|
||||
apiV1SystemBusMachineryAdd,
|
||||
apiV1SystemBusMachineryEdit,
|
||||
apiV1SystemBusMachineryDetail,
|
||||
addMachineChild,
|
||||
editMachineChild,
|
||||
detailMachineChild
|
||||
},
|
||||
rules: {
|
||||
id: [{ required: true, message: '主键id不能为空', trigger: 'blur' }]
|
||||
setup() {
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const loading = ref(false);
|
||||
const childLoading = ref(false);
|
||||
const queryRef = ref();
|
||||
const addRef = ref();
|
||||
const editRef = ref();
|
||||
const detailRef = ref();
|
||||
const addChildRef = ref();
|
||||
const editChildRef = ref();
|
||||
const deatilChildRef = ref();
|
||||
// 是否显示所有搜索选项
|
||||
const showAll = ref(false);
|
||||
// 非单个禁用
|
||||
const single = ref(true);
|
||||
// 非多个禁用
|
||||
const multiple = ref(true);
|
||||
const word = computed(() => {
|
||||
if (showAll.value === false) {
|
||||
//对文字进行处理
|
||||
return '展开搜索';
|
||||
} else {
|
||||
return '收起搜索';
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询机械列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listMachinery(queryParams.value);
|
||||
machineryList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
// 字典选项数据
|
||||
const account_status = ref([
|
||||
{
|
||||
label: '正常',
|
||||
value: '0'
|
||||
},
|
||||
{
|
||||
label: '停用',
|
||||
value: '1'
|
||||
}
|
||||
]);
|
||||
const stores = useUserStore();
|
||||
const state = reactive<BusMachineryTableDataState>({
|
||||
ids: [],
|
||||
tableData: {
|
||||
data: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
param: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
id: undefined,
|
||||
machineryName: undefined,
|
||||
status: undefined,
|
||||
createdAt: undefined,
|
||||
dateRange: [],
|
||||
projectId: stores.selectedProject.goId
|
||||
}
|
||||
},
|
||||
childrenData: {
|
||||
data: [],
|
||||
total: 0,
|
||||
param: {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
},
|
||||
expandKeys: [], // 需要展开行的sourceId数组
|
||||
typeOption: [
|
||||
{
|
||||
label: '入场',
|
||||
value: '2'
|
||||
},
|
||||
{
|
||||
label: '出场',
|
||||
value: '1'
|
||||
}
|
||||
]
|
||||
});
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
initTableData();
|
||||
});
|
||||
// 初始化表格数据
|
||||
const initTableData = () => {
|
||||
busMachineryList();
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
machineryFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
const resetQuery = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
busMachineryList();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: MachineryVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
// 获取列表数据
|
||||
const busMachineryList = () => {
|
||||
loading.value = true;
|
||||
listBusMachinery(state.tableData.param).then((res: any) => {
|
||||
console.log('🚀 ~ busMachineryList ~ res:', res);
|
||||
let list = res.data.list ?? [];
|
||||
state.tableData.data = list.map((item) => {
|
||||
item.children = {};
|
||||
item.children.data = [];
|
||||
item.children.total = 0;
|
||||
item.children.loading = false;
|
||||
return item;
|
||||
});
|
||||
state.tableData.total = res.data.total;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
// 施工类型状态字典翻译
|
||||
const statusFormat = (row: BusMachineryTableColumns) => {
|
||||
return proxy.selectDictLabel(account_status.value, row.status);
|
||||
};
|
||||
// 多选框选中数据
|
||||
const handleSelectionChange = (selection: Array<BusMachineryInfoData>) => {
|
||||
state.ids = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加机械';
|
||||
addRef.value.openDialog();
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: MachineryVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getMachinery(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改机械';
|
||||
const handleUpdate = (row: BusMachineryTableColumns) => {
|
||||
if (!row) {
|
||||
row = state.tableData.data.find((item: BusMachineryTableColumns) => {
|
||||
return item.id === state.ids[0];
|
||||
}) as BusMachineryTableColumns;
|
||||
}
|
||||
editRef.value.openDialog(toRaw(row));
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
machineryFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
form.value.projectId = currentProject.value?.id;
|
||||
if (form.value.id) {
|
||||
await updateMachinery(form.value).finally(() => (buttonLoading.value = false));
|
||||
/** 自定义编号 */
|
||||
const indexMethod = (index) => {
|
||||
let pageNum = state.tableData.param.pageNum - 1;
|
||||
if (pageNum !== -1 && pageNum !== 0) {
|
||||
return index + 1 + pageNum * state.tableData.param.pageSize;
|
||||
} else {
|
||||
await addMachinery(form.value).finally(() => (buttonLoading.value = false));
|
||||
return index + 1;
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
};
|
||||
const childDelete = (props, row: BusMachineryTableColumns) => {
|
||||
let msg = '你确定要删除所选数据?';
|
||||
let id: number[] = [];
|
||||
if (row) {
|
||||
msg = `此操作将永久删除数据,是否继续?`;
|
||||
id = [row.id];
|
||||
} else {
|
||||
id = state.ids;
|
||||
}
|
||||
if (id.length === 0) {
|
||||
ElMessage.error('请选择要删除的数据。');
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(msg, '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
delBusMachineryDetail(id).then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
busMachineryDetailList(props.children, props.id);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
const handleView = (row: BusMachineryTableColumns) => {
|
||||
detailRef.value.openDialog(toRaw(row));
|
||||
};
|
||||
// 获取当前行key
|
||||
const getRowKeys = (row: any) => {
|
||||
return row.id;
|
||||
};
|
||||
// 展开行change事件
|
||||
const expandChange = (row: any, expandedRows: any) => {
|
||||
// state.expandKeys = [row.id];
|
||||
//当行展示时调用接口
|
||||
if (expandedRows.length) {
|
||||
// state.expandKeys = [];
|
||||
// if(row) {
|
||||
// state.expandKeys.push(row.id)
|
||||
// }
|
||||
busMachineryDetailList(row.children, row.id);
|
||||
} else {
|
||||
// state.expandKeys = [];
|
||||
}
|
||||
};
|
||||
// 获取子级数据
|
||||
const busMachineryDetailList = (row, machinery_id: any) => {
|
||||
row.loading = true;
|
||||
listBusMachineryDetail({ ...state.childrenData.param, machinery_id: machinery_id }).then((res: any) => {
|
||||
let list = res.data.list ?? [];
|
||||
let filterOptions = [];
|
||||
if (list.length) {
|
||||
list = list.map((item) => {
|
||||
if (item.picture && item.picture.includes('[')) {
|
||||
item.picture = item.picture ? JSON.parse(item.picture) : [];
|
||||
} else {
|
||||
item.picture = item.picture ? item.picture.split(',') : [];
|
||||
}
|
||||
filterOptions.push({ text: item.checkoutNumber, value: item.checkoutNumber });
|
||||
return item;
|
||||
});
|
||||
}
|
||||
row.data = list;
|
||||
console.log('🚀 ~ busMachineryDetailList ~ row.data :', row.data);
|
||||
row.total = res.data.total;
|
||||
row.filterOptions = filterOptions;
|
||||
row.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: MachineryVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除机械编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delMachinery(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
// 添加子级数据
|
||||
const handleaddChild = (row: any) => {
|
||||
addChildRef.value.openDialog(toRaw(row));
|
||||
};
|
||||
const childUpdate = (props, row: any) => {
|
||||
if (!row) {
|
||||
row = state.tableData.data.find((item: any) => {
|
||||
return item.id === state.ids[0];
|
||||
}) as any;
|
||||
}
|
||||
editChildRef.value.openDialog(toRaw(props), toRaw(row));
|
||||
};
|
||||
const childView = (row: any) => {
|
||||
deatilChildRef.value.openDialog(toRaw(row));
|
||||
};
|
||||
const handleDelete = (row: any) => {
|
||||
let msg = '你确定要删除所选数据?';
|
||||
let id: number[] = [];
|
||||
if (row) {
|
||||
msg = `此操作将永久删除数据,是否继续?`;
|
||||
id = [row.id];
|
||||
} else {
|
||||
id = state.ids;
|
||||
}
|
||||
if (id.length === 0) {
|
||||
ElMessage.error('请选择要删除的数据。');
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(msg, '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
delBusMachinery(id).then(() => {
|
||||
ElMessage.success('删除成功');
|
||||
busMachineryList();
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
const filterHandler = (value: string, row: any, column: any) => {
|
||||
const property = column['property'];
|
||||
return row[property] === value;
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'machinery/machinery/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`machinery_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
const dialogRef = ref();
|
||||
const currentMachineryId = ref<number | string>(0);
|
||||
/** 添加机械出入场详情 */
|
||||
const handleAddMachineryDetail = (row?: MachineryVO) => {
|
||||
currentMachineryId.value = row.id ?? 0;
|
||||
dialogRef.value.openDialog();
|
||||
};
|
||||
|
||||
//监听项目id刷新数据
|
||||
/** 监听项目ID变化,刷新数据 */
|
||||
const listeningProject = watch(
|
||||
() => currentProject.value?.id,
|
||||
(nid, oid) => {
|
||||
queryParams.value.projectId = nid;
|
||||
form.value.projectId = nid;
|
||||
getList();
|
||||
() => stores.selectedProject.goId,
|
||||
(newId, oldId) => {
|
||||
if (newId !== oldId && newId) {
|
||||
state.tableData.param.projectId = newId;
|
||||
initTableData();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/** 页面卸载时清理监听 */
|
||||
onUnmounted(() => {
|
||||
listeningProject();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
return {
|
||||
proxy,
|
||||
addRef,
|
||||
editRef,
|
||||
detailRef,
|
||||
showAll,
|
||||
loading,
|
||||
single,
|
||||
multiple,
|
||||
word,
|
||||
queryRef,
|
||||
resetQuery,
|
||||
busMachineryList,
|
||||
statusFormat,
|
||||
account_status,
|
||||
handleSelectionChange,
|
||||
handleAdd,
|
||||
handleUpdate,
|
||||
handleDelete,
|
||||
handleView,
|
||||
indexMethod,
|
||||
getRowKeys,
|
||||
handleaddChild,
|
||||
childView,
|
||||
childUpdate,
|
||||
childDelete,
|
||||
addChildRef,
|
||||
editChildRef,
|
||||
deatilChildRef,
|
||||
busMachineryDetailList,
|
||||
childLoading,
|
||||
expandChange,
|
||||
filterHandler,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.colBlock {
|
||||
display: block;
|
||||
}
|
||||
.colNone {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
@ -137,12 +137,7 @@
|
||||
@change="(val) => selectName(val, scope.row, scope.$index)"
|
||||
>
|
||||
<!-- 动态过滤:排除当前行外已选中的物资ID -->
|
||||
<el-option
|
||||
v-for="item in getAvailableNameList(scope.$index)"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
<el-option v-for="item in getAvailableNameList(scope.$index)" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -426,11 +421,11 @@ const getAvailableNameList = (currentIndex: number) => {
|
||||
// 收集除当前行外已选中的物资ID
|
||||
const selectedIds = form.value.planList
|
||||
.filter((_, index) => index !== currentIndex)
|
||||
.map(item => item.suppliespriceId)
|
||||
.filter(id => id !== undefined && id !== null);
|
||||
.map((item) => item.suppliespriceId)
|
||||
.filter((id) => id !== undefined && id !== null);
|
||||
|
||||
// 过滤掉已选中的物资
|
||||
return nameList.value.filter(item => !selectedIds.includes(item.id));
|
||||
return nameList.value.filter((item) => !selectedIds.includes(item.id));
|
||||
};
|
||||
|
||||
/** 选择物资名称触发 */
|
||||
|
@ -228,8 +228,13 @@ const getMaterialsListData = async () => {
|
||||
label: item.materialsName + '_' + item.createTime,
|
||||
children: []
|
||||
}));
|
||||
if (TreeData.value.length > 0) {
|
||||
queryParams.value.materialsId = TreeData.value[0].id;
|
||||
getList();
|
||||
} else {
|
||||
queryParams.value.materialsId = '';
|
||||
getList();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -453,7 +458,7 @@ const listeningProject: WatchStopHandle = watch(
|
||||
Object.values(childRowStates.value).forEach((state) => {
|
||||
state.queryParams.projectId = newId;
|
||||
});
|
||||
getList();
|
||||
getMaterialsListData();
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -73,12 +73,12 @@
|
||||
</el-row>
|
||||
</el-form> -->
|
||||
<el-table :data="tableData" v-loading="loading" row-key="id" border>
|
||||
<el-table-column prop="num" label="编号" />
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column prop="specification" label="规格" />
|
||||
<el-table-column prop="unit" label="单位" />
|
||||
<el-table-column prop="quantity" label="数量" />
|
||||
<el-table-column prop="remark" label="备注" />
|
||||
<el-table-column align="center" prop="num" label="编号" />
|
||||
<el-table-column align="center" prop="name" label="名称" />
|
||||
<el-table-column align="center" prop="specification" label="规格" />
|
||||
<el-table-column align="center" prop="unit" label="单位" />
|
||||
<el-table-column align="center" prop="quantity" label="数量" />
|
||||
<el-table-column align="center" prop="remark" label="备注" />
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
@ -214,7 +214,7 @@ const getInfo = () => {
|
||||
console.log('res.data', masterDataRes);
|
||||
Object.assign(form.value, masterDataRes?.data[0]);
|
||||
// console.log('form', form.value);
|
||||
tableData.value = res.rows.reverse();//翻转
|
||||
tableData.value = res.rows; //正序显示
|
||||
loading.value = false;
|
||||
buttonLoading.value = false;
|
||||
});
|
||||
@ -319,9 +319,7 @@ onMounted(() => {
|
||||
.el-input__inner,
|
||||
.el-select .el-input__inner {
|
||||
border-radius: 4px;
|
||||
transition:
|
||||
border-color 0.2s,
|
||||
box-shadow 0.2s;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
|
||||
&:focus {
|
||||
border-color: var(--primary-light);
|
||||
@ -331,9 +329,7 @@ onMounted(() => {
|
||||
|
||||
.el-textarea__inner {
|
||||
border-radius: 4px;
|
||||
transition:
|
||||
border-color 0.2s,
|
||||
box-shadow 0.2s;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
|
||||
&:focus {
|
||||
border-color: var(--primary-light);
|
||||
|
@ -123,6 +123,8 @@ function addPre() {
|
||||
|
||||
// 视频播放
|
||||
function videoPlay(obj: any) {
|
||||
console.log('objobjobj',obj);
|
||||
|
||||
getAccessToken().then((res: any) => {
|
||||
if (res.code == 200 && obj.deviceSerial) {
|
||||
flvPlayer.value = new EZUIKit.EZUIKitPlayer({
|
||||
|
@ -34,9 +34,9 @@
|
||||
<template #default="scope">
|
||||
<el-image
|
||||
:z-index="9999"
|
||||
:preview-src-list="['http://58.17.134.85:8919' + scope.row.path]"
|
||||
:preview-src-list="['http://58.17.134.85:8920' + scope.row.path]"
|
||||
preview-teleported
|
||||
:src="'http://58.17.134.85:8919' + scope.row.path"
|
||||
:src="'http://58.17.134.85:8920' + scope.row.path"
|
||||
class="w20"
|
||||
/>
|
||||
</template>
|
||||
|
@ -19,9 +19,9 @@
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['out:constructionValue:add']">新增</el-button>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -39,8 +39,16 @@
|
||||
<el-table-column label="人工填报数量" align="center" prop="artificialNum" />
|
||||
<el-table-column label="无人机识别数量" align="center" prop="uavNum" />
|
||||
<el-table-column label="确认数量" align="center" prop="confirmNum" />
|
||||
<el-table-column label="对乙产值" align="center" prop="outValue" />
|
||||
<el-table-column label="对甲产值" align="center" prop="ownerValue" />
|
||||
<el-table-column label="对乙产值" align="center" prop="outValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.outValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="对甲产值" align="center" prop="ownerValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="流程状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="wf_business_status" :value="scope.row.auditStatus" />
|
||||
|
@ -24,9 +24,21 @@
|
||||
<el-table v-loading="loading" :data="monthPlanList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="计划月份" align="center" prop="planMonth" />
|
||||
<el-table-column label="计划产值" align="center" prop="planValue" />
|
||||
<el-table-column label="完成产值" align="center" prop="completeValue" />
|
||||
<el-table-column label="差额" align="center" prop="differenceValue" />
|
||||
<el-table-column label="计划产值" align="center" prop="planValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.planValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="完成产值" align="center" prop="completeValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.completeValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="差额" align="center" prop="differenceValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.differenceValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" align="center">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.type == '1'">对甲</span>
|
||||
|
@ -40,9 +40,21 @@
|
||||
<el-table v-loading="loading" :data="monthPlanList">
|
||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||
<el-table-column label="计划月份" align="center" prop="planMonth" />
|
||||
<el-table-column label="计划产值(元)" align="center" prop="planValue" />
|
||||
<el-table-column label="完成产值(元)" align="center" prop="completeValue" />
|
||||
<el-table-column label="差额(元)" align="center" prop="differenceValue" />
|
||||
<el-table-column label="计划产值(元)" align="center" prop="planValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.planValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="完成产值(元)" align="center" prop="completeValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.completeValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="差额(元)" align="center" prop="differenceValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.differenceValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产值类型" align="center" prop="valueType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="out_value_type" :value="scope.row.valueType" />
|
||||
@ -104,7 +116,7 @@
|
||||
<script setup name="MonthPlan" lang="ts">
|
||||
import { listMonthPlan, getMonthPlan, delMonthPlan, addMonthPlan, updateMonthPlan } from '@/api/out/monthPlan';
|
||||
import { MonthPlanVO } from '@/api/out/monthPlan/types';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const { out_value_type } = toRefs<any>(proxy?.useDict('out_value_type'));
|
||||
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
||||
|
||||
|
@ -31,11 +31,27 @@
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="monthPlanAuditList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="设计产值(元)" align="center" prop="designValue" />
|
||||
<el-table-column label="采购产值(元)" align="center" prop="purchaseValue" />
|
||||
<el-table-column label="施工产值(元)" align="center" prop="constructionValue" />
|
||||
<el-table-column label="总产值(元)" align="center" prop="totalValue" />
|
||||
<el-table-column type="index" width="55" label="序号" align="center" />
|
||||
<el-table-column label="设计产值(元)" align="center" prop="designValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.designValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="采购产值(元)" align="center" prop="purchaseValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.purchaseValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="施工产值(元)" align="center" prop="constructionValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.constructionValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总产值(元)" align="center" prop="totalValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划月份" align="center" prop="planMonth" />
|
||||
</el-table>
|
||||
|
||||
|
@ -26,12 +26,32 @@
|
||||
|
||||
<el-table v-loading="loading" :data="valueAllocationList">
|
||||
<el-table-column label="项目" align="center" prop="projectName" />
|
||||
<el-table-column label="月预计产值" align="center" prop="monthEstimatedValue" />
|
||||
<el-table-column label="完成产值月合计" align="center" prop="monthCompletionValue" />
|
||||
<el-table-column label="产值差额" align="center" prop="valueDifference" />
|
||||
<el-table-column label="项目总产值" align="center" prop="totalValue" />
|
||||
<el-table-column label="累计完成产值" align="center" prop="accumulatedCompletionValue" />
|
||||
<el-table-column label="项目完成率" align="center" prop="projectCompletionRate" />
|
||||
<el-table-column label="月预计产值" align="center" prop="monthEstimatedValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.monthEstimatedValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="完成产值月合计" align="center" prop="monthCompletionValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.monthCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="产值差额" align="center" prop="valueDifference">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.valueDifference) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="项目总产值" align="center" prop="totalValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="累计完成产值" align="center" prop="accumulatedCompletionValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.accumulatedCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="项目完成率" align="center" prop="projectCompletionRate"></el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
@ -48,7 +68,7 @@
|
||||
|
||||
<script setup name="ValueAllocation" lang="ts">
|
||||
import { listOutTable } from '@/api/out/outDesignTable';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { dayjs } from 'element-plus';
|
||||
// 获取用户 store
|
||||
|
@ -23,9 +23,21 @@
|
||||
<el-card shadow="never">
|
||||
<el-table v-loading="loading" :data="tableData" v-if="activeTab == '1' || activeTab == '2'">
|
||||
<el-table-column label="项目" align="center" prop="projectName" />
|
||||
<el-table-column label="累计完工产值" align="center" prop="totalCompletionOutputValue" />
|
||||
<el-table-column label="累计结算产值" align="center" prop="totalSettlementOutputValue" />
|
||||
<el-table-column label="完工未结算额" align="center" prop="completionUnsettledAmount" />
|
||||
<el-table-column label="累计完工产值" align="center" prop="totalCompletionOutputValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalCompletionOutputValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="累计结算产值" align="center" prop="totalSettlementOutputValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalSettlementOutputValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="完工未结算额" align="center" prop="completionUnsettledAmount">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.completionUnsettledAmount) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="完工未结算比例" align="center" prop="completionUnsettledRatio" />
|
||||
<!-- <el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
@ -36,9 +48,21 @@
|
||||
<el-table v-loading="loading" :data="tableData" v-if="activeTab == '3'">
|
||||
<el-table-column label="项目" align="center" prop="projectName" />
|
||||
<!-- <el-table-column label="累计完工产值" align="center" prop="totalCompletionOutputValue" /> -->
|
||||
<el-table-column label="分包累计结算产值" align="center" prop="subTotalSettlementOutputValue" />
|
||||
<el-table-column label="业主累计结算产值" align="center" prop="ownerTotalSettlementOutputValue" />
|
||||
<el-table-column label="差额" align="center" prop="differenceValue" />
|
||||
<el-table-column label="分包累计结算产值" align="center" prop="subTotalSettlementOutputValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.subTotalSettlementOutputValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="业主累计结算产值" align="center" prop="ownerTotalSettlementOutputValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerTotalSettlementOutputValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="差额" align="center" prop="differenceValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.differenceValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<!-- <el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" @click="handleEdit(scope.row)" link icon="Position">联查分包结算</el-button>
|
||||
@ -47,12 +71,36 @@
|
||||
</el-table>
|
||||
<el-table v-loading="loading" :data="tableData" v-if="activeTab == '4'">
|
||||
<el-table-column label="项目" align="center" prop="projectName" />
|
||||
<el-table-column label="对甲计划总产值" align="center" prop="ownerTotal" />
|
||||
<el-table-column label="对乙计划总产值" align="center" prop="subTotal" />
|
||||
<el-table-column label="对甲月计划产值" align="center" prop="ownerPlanTotal" />
|
||||
<el-table-column label="对乙月计划产值" align="center" prop="subPlanTotal" />
|
||||
<el-table-column label="对甲月实际产值" align="center" prop="ownerActualTotal" />
|
||||
<el-table-column label="对乙月实际产值" align="center" prop="subActualTotal" />
|
||||
<el-table-column label="对甲计划总产值" align="center" prop="ownerTotal">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerTotal) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对乙计划总产值" align="center" prop="subTotal">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.subTotal) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对甲月计划产值" align="center" prop="ownerPlanTotal">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerPlanTotal) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对乙月计划产值" align="center" prop="subPlanTotal">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.subPlanTotal) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对甲月实际产值" align="center" prop="ownerActualTotal">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerActualTotal) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对乙月实际产值" align="center" prop="subActualTotal">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.subActualTotal) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<!-- <el-table-column label="操作" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" @click="handleEdit(scope.row)" link icon="Position">联查分包结算</el-button>
|
||||
@ -75,7 +123,7 @@
|
||||
<script setup lang="ts">
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { listOutTable, comparisonOfOutputValue, comparisonOfSettlementValue } from '@/api/out/outDesignTableVS/index';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
import { dayjs } from 'element-plus';
|
||||
const userStore = useUserStoreHook();
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
|
@ -16,18 +16,66 @@
|
||||
<el-card shadow="never">
|
||||
<el-table v-loading="loading" :data="tableData">
|
||||
<el-table-column label="项目" align="center" prop="projectName" />
|
||||
<el-table-column label="项目总产值" align="center" prop="totalValue" />
|
||||
<el-table-column label="月预计产值" align="center" prop="monthlyEstimatedValue" />
|
||||
<el-table-column label="完成产值(第一周)" align="center" prop="firstWeekCompletionValue" />
|
||||
<el-table-column label="完成产值(第二周)" align="center" prop="secondWeekCompletionValue" />
|
||||
<el-table-column label="完成产值(第三周)" align="center" prop="thirdWeekCompletionValue" />
|
||||
<el-table-column label="完成产值(第四周)" align="center" prop="fourthWeekCompletionValue" />
|
||||
<el-table-column label="完成产值(第五周)" align="center" prop="fifthWeekCompletionValue" />
|
||||
<el-table-column label="完成产值月合计" align="center" prop="totalCompletionValue" />
|
||||
<el-table-column label="产值差额" align="center" prop="valueDifference" />
|
||||
<el-table-column label="预计累计产值" align="center" prop="estimatedAccumulatedValue" />
|
||||
<el-table-column label="累计完成产值" align="center" prop="accumulatedCompletionValue" />
|
||||
<el-table-column label="产值差额" align="center" prop="valueDifferenceAccumulation" />
|
||||
<el-table-column label="项目总产值" align="center" prop="totalValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="月预计产值" align="center" prop="monthlyEstimatedValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.monthlyEstimatedValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="完成产值(第一周)" align="center" prop="firstWeekCompletionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.firstWeekCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="完成产值(第二周)" align="center" prop="secondWeekCompletionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.secondWeekCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="完成产值(第三周)" align="center" prop="thirdWeekCompletionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.thirdWeekCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="完成产值(第四周)" align="center" prop="fourthWeekCompletionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.fourthWeekCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="完成产值(第五周)" align="center" prop="fifthWeekCompletionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.fifthWeekCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="完成产值月合计" align="center" prop="totalCompletionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="产值差额" align="center" prop="valueDifference"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.valueDifference) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="预计累计产值" align="center" prop="estimatedAccumulatedValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.estimatedAccumulatedValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="累计完成产值" align="center" prop="accumulatedCompletionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.accumulatedCompletionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="产值差额" align="center" prop="valueDifferenceAccumulation"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.valueDifferenceAccumulation) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="项目完成总进度" align="center" prop="totalCompletionProgress" />
|
||||
</el-table>
|
||||
<pagination
|
||||
@ -50,6 +98,7 @@ import { listOutTable } from '@/api/out/outTable';
|
||||
const userStore = useUserStoreHook();
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const activeTab = ref('1');
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const queryParams = ref({
|
||||
month: '',
|
||||
pageNum: 1,
|
||||
@ -110,7 +159,7 @@ const resetMonth=()=>{
|
||||
// 形成"YYYY-M"格式
|
||||
const formattedDate = `${year}-${String(month).padStart(2, '0')}`;
|
||||
queryParams.value.month = formattedDate;
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
resetMonth();
|
||||
|
||||
|
@ -12,7 +12,11 @@
|
||||
<el-table-column label="规格" align="center" prop="specification" />
|
||||
<el-table-column label="单位" align="center" prop="unit" />
|
||||
<el-table-column label="接收数量" align="center" prop="acceptedQuantity" />
|
||||
<el-table-column label="价格" align="center" prop="unitPrice"> </el-table-column>
|
||||
<el-table-column label="价格" align="center" prop="unitPrice">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.unitPrice) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark"> </el-table-column>
|
||||
<el-table-column label="操作" align="center" prop="remark" v-if="queryParams.type == '1'">
|
||||
<template #default="scope">
|
||||
|
@ -48,7 +48,11 @@
|
||||
<span>{{ parseTime(scope.row.settlementDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结算产值" align="center" prop="settlementValue" />
|
||||
<el-table-column label="结算产值" align="center" prop="settlementValue" >
|
||||
<template #default="scope">
|
||||
<span>{{ proxy.formatPrice(scope.row.settlementValue) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="说明" align="center" prop="remark" />
|
||||
<el-table-column label="合同编码" align="center" prop="contractCode" />
|
||||
<el-table-column label="合同名称" align="center" prop="contractName" />
|
||||
|
@ -17,14 +17,46 @@
|
||||
|
||||
<el-table v-loading="loading" :data="valueAllocationList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="对甲总产值" align="center" prop="ownerTotalValue" />
|
||||
<el-table-column label="对甲设计产值" align="center" prop="ownerDesignValue" />
|
||||
<el-table-column label="对甲采购产值" align="center" prop="ownerPurchaseValue" />
|
||||
<el-table-column label="对甲施工产值" align="center" prop="ownerConstructionValue" />
|
||||
<el-table-column label="对乙总产值" align="center" prop="subTotalValue" />
|
||||
<el-table-column label="对乙设计产值" align="center" prop="subDesignValue" />
|
||||
<el-table-column label="对乙采购产值" align="center" prop="subPurchaseValue" />
|
||||
<el-table-column label="对乙施工产值" align="center" prop="subConstructionValue" />
|
||||
<el-table-column label="对甲总产值" align="center" prop="ownerTotalValue">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerTotalValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="对甲设计产值" align="center" prop="ownerDesignValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerDesignValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对甲采购产值" align="center" prop="ownerPurchaseValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerPurchaseValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对甲施工产值" align="center" prop="ownerConstructionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.ownerConstructionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对乙总产值" align="center" prop="subTotalValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.subTotalValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对乙设计产值" align="center" prop="subDesignValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.subDesignValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对乙采购产值" align="center" prop="subPurchaseValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.subPurchaseValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="对乙施工产值" align="center" prop="subConstructionValue"
|
||||
><template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.subConstructionValue) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
|
@ -1,12 +1,14 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
||||
:leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="请选择项目:" prop="pid" label-width="100">
|
||||
<el-select v-model="queryParams.projectId" placeholder="请选择" @change="handleChange" clearable>
|
||||
<el-option v-for="item in matrixOptions" :key="item.projectId" :label="item.name" :value="item.projectId" />
|
||||
<el-option v-for="item in matrixOptions" :key="item.projectId" :label="item.name"
|
||||
:value="item.projectId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="请选择方阵:" prop="pid" label-width="100" v-if="relevancyStructure == '2'">
|
||||
@ -21,24 +23,16 @@
|
||||
<el-tabs type="border-card" v-model="activeTab" @tab-click="handleTabClick">
|
||||
<el-tab-pane :label="item.name" v-for="item in tabList" :key="item.id" :name="item.id"></el-tab-pane>
|
||||
<el-card shadow="never">
|
||||
<el-table
|
||||
ref="progressCategoryTableRef"
|
||||
v-loading="loading"
|
||||
:data="progressCategoryList"
|
||||
row-key="id"
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
v-if="isExpand"
|
||||
border
|
||||
>
|
||||
<el-table ref="progressCategoryTableRef" v-loading="loading" :data="progressCategoryList" row-key="id"
|
||||
:default-expand-all="isExpandAll" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
v-if="isExpand" border>
|
||||
<el-table-column label="" width="50" type="expand">
|
||||
<template #header>
|
||||
<el-icon
|
||||
class="cursor-pointer text-4! transform-rotate-z--90 transition-all-300"
|
||||
<el-icon class="cursor-pointer text-4! transform-rotate-z--90 transition-all-300"
|
||||
:class="!isExpandAll ? 'transform-rotate-z--90' : 'transform-rotate-z-90'"
|
||||
@click="handleToggleExpandAll"
|
||||
><Expand
|
||||
/></el-icon>
|
||||
@click="handleToggleExpandAll">
|
||||
<Expand />
|
||||
</el-icon>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-card class="pl-25" shadow="hover">
|
||||
@ -46,9 +40,8 @@
|
||||
<el-table-column label="名称" align="center" prop="name" width="170">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip :content="row.remark" placement="top" effect="dark" v-if="row.remark">
|
||||
<span class="flex items-center justify-center"
|
||||
><i class="iconfont icon-wenhao mr-0.5 text-3.5! text-#999"></i>{{ row.name }}</span
|
||||
>
|
||||
<span class="flex items-center justify-center"><i
|
||||
class="iconfont icon-wenhao mr-0.5 text-3.5! text-#999"></i>{{ row.name }}</span>
|
||||
</el-tooltip>
|
||||
<span v-else>{{ row.name }}</span>
|
||||
</template>
|
||||
@ -60,7 +53,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="是否延期" align="center" prop="isDelay" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.isDelay == '1' ? 'danger' : 'primary'">{{ row.isDelay == '1' ? '是' : '否' }}</el-tag>
|
||||
<el-tag :type="row.isDelay == '1' ? 'danger' : 'primary'">{{ row.isDelay == '1' ? '是' : '否'
|
||||
}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计量方式" align="center" prop="unitType" width="100">
|
||||
@ -71,7 +65,8 @@
|
||||
<el-table-column label="总量" align="center" prop="total" width="100" />
|
||||
<el-table-column label="总进度" align="center" prop="projectId">
|
||||
<template #default="{ row }">
|
||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" />
|
||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage"
|
||||
status="success" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划总量" align="center" prop="planTotal" width="100" />
|
||||
@ -87,35 +82,17 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="warning"
|
||||
icon="Download"
|
||||
link
|
||||
size="small"
|
||||
v-if="scope.row.name === '光伏板'"
|
||||
<el-button type="warning" icon="Download" link size="small" v-if="scope.row.name === '光伏板'"
|
||||
@click="openDialog(scope.row, 'importTableStatus', '上传表格')"
|
||||
v-hasPermi="['progress:progressCategory:add']"
|
||||
>
|
||||
v-hasPermi="['progress:progressCategory:add']">
|
||||
导入表格
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
icon="Plus"
|
||||
link
|
||||
size="small"
|
||||
@click="planRef.openDialog(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:add']"
|
||||
>
|
||||
<el-button type="success" icon="Plus" link size="small" @click="planRef.openDialog(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:add']">
|
||||
计划
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="Plus"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDayAdd(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:add']"
|
||||
>
|
||||
<el-button type="primary" icon="Plus" link size="small" @click="handleDayAdd(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:add']">
|
||||
日报
|
||||
</el-button>
|
||||
</template>
|
||||
@ -132,7 +109,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="总进度" align="center" prop="projectId">
|
||||
<template #default="{ row }">
|
||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" />
|
||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage"
|
||||
status="success" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -140,7 +118,8 @@
|
||||
<el-table-column label="名称" align="center" prop="name" width="170">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip :content="row.remark" placement="top" effect="dark" v-if="row.remark">
|
||||
<span class="flex items-center justify-center"><i class="iconfont icon-wenhao mr-0.5 text-3.5! text-#999"></i>{{ row.name }}</span>
|
||||
<span class="flex items-center justify-center"><i
|
||||
class="iconfont icon-wenhao mr-0.5 text-3.5! text-#999"></i>{{ row.name }}</span>
|
||||
</el-tooltip>
|
||||
<span v-else>{{ row.name }}</span>
|
||||
</template>
|
||||
@ -163,7 +142,8 @@
|
||||
<el-table-column label="总量" align="center" prop="total" width="100" />
|
||||
<el-table-column label="总进度" align="center" prop="projectId">
|
||||
<template #default="{ row }">
|
||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage" status="success" />
|
||||
<el-progress :text-inside="true" :stroke-width="20" :percentage="row.completedPercentage"
|
||||
status="success" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划总量" align="center" prop="planTotal" width="100" />
|
||||
@ -179,28 +159,17 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="warning"
|
||||
icon="Download"
|
||||
link
|
||||
size="small"
|
||||
v-if="scope.row.name === '光伏板'"
|
||||
<el-button type="warning" icon="Download" link size="small" v-if="scope.row.name === '光伏板'"
|
||||
@click="openDialog(scope.row, 'importTableStatus', '上传表格')"
|
||||
v-hasPermi="['progress:progressCategory:add']"
|
||||
>
|
||||
v-hasPermi="['progress:progressCategory:add']">
|
||||
导入表格
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
icon="Plus"
|
||||
link
|
||||
size="small"
|
||||
@click="planRef.openDialog(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:add']"
|
||||
>
|
||||
<el-button type="success" icon="Plus" link size="small" @click="planRef.openDialog(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:add']">
|
||||
计划
|
||||
</el-button>
|
||||
<el-button type="primary" icon="Plus" link size="small" @click="handleDayAdd(scope.row)" v-hasPermi="['progress:progressCategory:add']">
|
||||
<el-button type="primary" icon="Plus" link size="small" @click="handleDayAdd(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:add']">
|
||||
日报
|
||||
</el-button>
|
||||
</template>
|
||||
@ -211,7 +180,8 @@
|
||||
|
||||
<!-- 导入数据对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.importDataStatus" width="500px" append-to-body>
|
||||
<file-upload class="pl-20 pt" v-model="dialog.file" :limit="20" :file-size="50" :file-type="['shp', 'shx', 'dbf']" />
|
||||
<file-upload class="pl-20 pt" v-model="dialog.file" :limit="20" :file-size="50"
|
||||
:file-type="['shp', 'shx', 'dbf']" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
@ -415,9 +385,13 @@ const handleChange = (value: number) => {
|
||||
const handleDayAdd = (row: ProgressCategoryVO) => {
|
||||
if (row.unitType === '2') {
|
||||
dailyRef.value.openDialog(row);
|
||||
} else {
|
||||
if (!row.workType) {
|
||||
dailyRef.value.openDialog(row);
|
||||
} else {
|
||||
dailyRateRef.value.openDialog(row);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 导入按钮操作 */
|
||||
|
@ -1,12 +1,14 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
|
||||
:leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="请选择项目:" prop="pid" label-width="100">
|
||||
<el-select v-model="queryParams.projectId" placeholder="请选择" @change="handleChange" clearable>
|
||||
<el-option v-for="item in matrixOptions" :key="item.projectId" :label="item.name" :value="item.projectId" />
|
||||
<el-option v-for="item in matrixOptions" :key="item.projectId" :label="item.name"
|
||||
:value="item.projectId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="请选择方阵:" prop="pid" label-width="100" v-if="relevancyStructure == '2'">
|
||||
@ -27,13 +29,8 @@
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd()">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<file-upload
|
||||
upload-url="/progress/progressCategory/import"
|
||||
v-model="file"
|
||||
:limit="1"
|
||||
:file-type="['xls', 'xlsx']"
|
||||
:on-upload-success="handleSuccess"
|
||||
>
|
||||
<file-upload upload-url="/progress/progressCategory/import" v-model="file" :limit="1"
|
||||
:file-type="['xls', 'xlsx']" :on-upload-success="handleSuccess">
|
||||
<el-button type="primary" plain icon="upload">导入</el-button>
|
||||
</file-upload>
|
||||
</el-col>
|
||||
@ -43,17 +40,39 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
|
||||
</el-col>
|
||||
<el-col :span="6" :push="6">
|
||||
<div class="summary-container">
|
||||
<div class="summary-card owner-summary">
|
||||
<div class="summary-icon">
|
||||
<el-icon size="24">
|
||||
<Money />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="summary-content">
|
||||
<div class="summary-label">产值金额(业主)</div>
|
||||
<div class="summary-value">{{ ownerOutputSum }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="summary-card construction-summary">
|
||||
<div class="summary-icon">
|
||||
<el-icon size="24">
|
||||
<Wallet />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="summary-content">
|
||||
<div class="summary-label">产值金额(分包)</div>
|
||||
<div class="summary-value">{{ constructionOutputSum }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
|
||||
</el-row>
|
||||
</template>
|
||||
<el-table
|
||||
ref="progressCategoryTableRef"
|
||||
v-loading="loading"
|
||||
:data="progressCategoryList"
|
||||
row-key="id"
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table ref="progressCategoryTableRef" v-loading="loading" :data="progressCategoryList" row-key="id"
|
||||
:default-expand-all="isExpandAll" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
max-height="550">
|
||||
<!-- <el-table-column label="父类别id" prop="parentId" /> -->
|
||||
<el-table-column label="类别名称" prop="name" width="230" />
|
||||
<el-table-column label="计量方式" align="center" prop="unitType">
|
||||
@ -69,22 +88,22 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="综合单价(业主)" align="center" prop="ownerPrice">
|
||||
<template #default="{ row }">
|
||||
{{ row.unitType == 0 ? '' : row.ownerPrice }}
|
||||
{{ row.unitType == 0 ? '' : proxy.formatPrice(row.ownerPrice) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="综合单价(分包)" align="center" prop="constructionPrice">
|
||||
<template #default="{ row }">
|
||||
{{ row.unitType == 0 ? '' : row.constructionPrice }}
|
||||
{{ row.unitType == 0 ? '' : proxy.formatPrice(row.constructionPrice) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产值金额(业主)" align="center" prop="ownerOutputValue">
|
||||
<template #default="{ row }">
|
||||
{{ row.unitType == 0 ? '' : row.ownerOutputValue }}
|
||||
{{ row.unitType == 0 ? '' : proxy.formatPrice(row.ownerOutputValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产值金额(分包)" align="center" prop="constructionOutputValue">
|
||||
<template #default="{ row }">
|
||||
{{ row.unitType == 0 ? '' : row.constructionOutputValue }}
|
||||
{{ row.unitType == 0 ? '' : proxy.formatPrice(row.constructionOutputValue) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总数量" align="center" prop="total">
|
||||
@ -102,10 +121,12 @@
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['progress:progressCategory:edit']">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:edit']">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['progress:progressCategory:remove']">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
|
||||
v-hasPermi="['progress:progressCategory:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
@ -119,14 +140,9 @@
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="progressCategoryFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="父类别" prop="parentId" v-if="!form.id">
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="progressCategoryOptions"
|
||||
:props="{ value: 'id', label: 'name', children: 'children' }"
|
||||
value-key="id"
|
||||
placeholder="请选择父类别"
|
||||
check-strictly
|
||||
/>
|
||||
<el-tree-select v-model="form.parentId" :data="progressCategoryOptions"
|
||||
:props="{ value: 'id', label: 'name', children: 'children' }" value-key="id" placeholder="请选择父类别"
|
||||
check-strictly />
|
||||
</el-form-item>
|
||||
<el-form-item label="计量方式" prop="unitType" v-if="!form.workType && form.unitType != '0'">
|
||||
<el-select v-model="form.unitType" placeholder="请选择关联数据">
|
||||
@ -191,8 +207,9 @@ import {
|
||||
import { ProgressCategoryVO, ProgressCategoryQuery, ProgressCategoryForm } from '@/api/progress/progressCategory/types';
|
||||
import { getTabList } from '@/api/progress/progressCategoryTemplate';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { Money, Wallet } from '@element-plus/icons-vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const { progress_unit_type, progress_work_type } = toRefs<any>(proxy?.useDict('progress_unit_type', 'progress_work_type'));
|
||||
const activeTab = ref('0');
|
||||
const relevancyStructure = ref('1');
|
||||
@ -225,7 +242,7 @@ const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const tempData = ref([])
|
||||
const initFormData: ProgressCategoryForm = {
|
||||
id: undefined,
|
||||
parentId: undefined,
|
||||
@ -291,7 +308,20 @@ const data = reactive<PageData<ProgressCategoryForm, ProgressCategoryQuery>>({
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
const matrixIdList = ref([]);
|
||||
|
||||
const ownerOutputSum = computed(() => {
|
||||
let sum = 0;
|
||||
tempData.value.forEach(item => {
|
||||
sum += Number(item.ownerOutputValue);
|
||||
})
|
||||
return proxy.formatPrice(sum);
|
||||
});
|
||||
const constructionOutputSum = computed(() => {
|
||||
let sum = 0;
|
||||
tempData.value.forEach(item => {
|
||||
sum += Number(item.constructionOutputValue);
|
||||
})
|
||||
return proxy.formatPrice(sum);
|
||||
});
|
||||
/** 查询分项工程单价列表 */
|
||||
const getList = async () => {
|
||||
if (!queryParams.value.projectId) {
|
||||
@ -310,6 +340,7 @@ const getList = async () => {
|
||||
matrixId: item.projectId
|
||||
};
|
||||
});
|
||||
|
||||
if (!matrixValue.value) matrixValue.value = matrixList[0].id;
|
||||
matrixOptions.value = matrixList;
|
||||
queryParams.value.projectId = matrixList[0].projectId;
|
||||
@ -325,6 +356,7 @@ const getList = async () => {
|
||||
try {
|
||||
const id = relevancyStructure.value == '2' ? matrixValue.value : activeTab.value;
|
||||
const res = await listProgressCategory(id);
|
||||
tempData.value = res.data;
|
||||
const data = proxy?.handleTree<ProgressCategoryVO>(res.data, 'id', 'parentId');
|
||||
if (data) {
|
||||
progressCategoryList.value = data;
|
||||
@ -506,3 +538,89 @@ onUnmounted(() => {
|
||||
listeningProject();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.summary-container {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.summary-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px 20px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #e4e7ed;
|
||||
background: #ffffff;
|
||||
min-width: 200px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.summary-card:hover {
|
||||
border-color: #c0c4cc;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.owner-summary {
|
||||
background: #f8f9fa;
|
||||
border-color: #409eff;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.construction-summary {
|
||||
background: #f8f9fa;
|
||||
border-color: #67c23a;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.summary-icon {
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
background: #f0f2f5;
|
||||
}
|
||||
|
||||
.owner-summary .summary-icon {
|
||||
background: #e6f7ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.construction-summary .summary-icon {
|
||||
background: #f0f9ff;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.summary-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.summary-label {
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.summary-value {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.summary-container {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.summary-card {
|
||||
min-width: 180px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
395
src/views/project/attendance/component/detail.vue
Normal file
@ -0,0 +1,395 @@
|
||||
<template>
|
||||
<div class="wxApplet-busAttendance-Detail">
|
||||
<el-dialog v-model="isShowDialog" width="1300px" :close-on-click-modal="false" :destroy-on-close="true" custom-class="busAttendance_detail">
|
||||
<template #header>
|
||||
<div v-drag="['.wxApplet-busAttendance-Detail .el-dialog', '.wxApplet-busAttendance-Detail .el-dialog__header']"></div>
|
||||
</template>
|
||||
<div class="content">
|
||||
<el-calendar ref="calendarRef" v-model="queryParams.dateStr">
|
||||
<template #header="{ date }">
|
||||
<div class="title">
|
||||
<el-button-group>
|
||||
<el-button type="primary" @click="selectDate('prev-month')">
|
||||
<el-icon class="el-icon--right"><ArrowLeft /></el-icon>上一月
|
||||
</el-button>
|
||||
<el-button type="primary" @click="selectDate('next-month')">
|
||||
下一月<el-icon class="el-icon--right"><ArrowRight /></el-icon>
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<span class="label">{{ date }} — {{ userInfo.UserName }}出勤</span>
|
||||
<div class="status-detail">
|
||||
<div class="dot1">全天考勤正常</div>
|
||||
<div class="dot2">当天存在异常迟到、早退、缺卡</div>
|
||||
<div class="dot3">当天提交过补卡申请</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #date-cell="{ data }">
|
||||
<div class="time-cell" v-if="getTime(data.day, true) || getTime(data.day, false)">
|
||||
<div class="status">
|
||||
<p class="time">{{ data.day.split('-').slice(1).join('-') }}</p>
|
||||
<div class="flex-r">
|
||||
<div class="circle status1" v-if="setFilterDay(data.day, 1)"></div>
|
||||
<div class="circle status2" v-if="setFilterDay(data.day, 2)"></div>
|
||||
<div class="circle status3" v-if="setFilterDay(data.day, 3)"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-c">
|
||||
<div class="row normal" v-if="getTime(data.day, true)">
|
||||
<span>{{ getTime(data.day, true) }}</span>
|
||||
<span style="padding-left: 5px">上班打卡</span>
|
||||
</div>
|
||||
<div class="row abnormal2" v-if="getTime(data.day, false)">
|
||||
<span>{{ getTime(data.day, false) }}</span>
|
||||
<span style="padding-left: 5px">下班打卡</span>
|
||||
</div>
|
||||
<div class="row abnormal3" v-if="getTime(data.day, false, true)">
|
||||
<span style="padding-left: 5px">下班缺卡</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="flex-c">
|
||||
<p class="time">{{ data.day.split('-').slice(1).join('-') }}</p>
|
||||
<img src="@/assets/icons/svg/empty-CZvxqguX.png" />
|
||||
<span>暂无打卡记录</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-calendar>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { reactive, toRefs, defineComponent, ref, unref, getCurrentInstance, nextTick } from 'vue';
|
||||
import { ElMessage, ElLoading } from 'element-plus';
|
||||
import { listAttendanceMonth } from '@/api/project/attendance';
|
||||
export default defineComponent({
|
||||
name: 'index',
|
||||
props: {
|
||||
isPinchOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const { proxy } = <any>getCurrentInstance();
|
||||
const formRef = ref<HTMLElement | null>(null);
|
||||
const menuRef = ref();
|
||||
const calendarRef = ref();
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
isShowDialog: false,
|
||||
isNormal: true,
|
||||
userInfo: {},
|
||||
queryParams: {
|
||||
openid: '',
|
||||
dateStr: ''
|
||||
},
|
||||
Daylist: [] //
|
||||
});
|
||||
// 打开弹窗
|
||||
const openDialog = (row) => {
|
||||
state.isShowDialog = true;
|
||||
if (row) {
|
||||
state.queryParams.openid = row.Openid;
|
||||
state.queryParams.dateStr = proxy.parseTime(new Date(), '{y}-{m}');
|
||||
state.userInfo = row;
|
||||
nextTick(() => {
|
||||
getList();
|
||||
});
|
||||
}
|
||||
};
|
||||
//获取数据
|
||||
const getList = () => {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '正在加载中……',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
target: '.busAttendance_detail'
|
||||
});
|
||||
listAttendanceMonth(state.queryParams as any).then((res: any) => {
|
||||
loading.close();
|
||||
let list = res.data.list ?? [];
|
||||
state.Daylist = list;
|
||||
});
|
||||
};
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
// 取消
|
||||
const onCancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
const selectDate = (val: any) => {
|
||||
if (!calendarRef.value) return;
|
||||
calendarRef.value.selectDate(val);
|
||||
state.queryParams.dateStr = proxy.parseTime(new Date(state.queryParams.dateStr), '{y}-{m}');
|
||||
getList();
|
||||
};
|
||||
const setFilterDay = (day, key) => {
|
||||
let arr = [1, 2, 3, 4, 5]; //1正常,2迟到,3早退,4缺勤,5补卡
|
||||
let flag = false;
|
||||
if (state.Daylist && state.Daylist.length) {
|
||||
let arr = state.Daylist;
|
||||
for (let index = 0; index < arr.length; index++) {
|
||||
const item = arr[index];
|
||||
if (item.PrintingDate == day) {
|
||||
let IsPinch1 = item.threelist[0].IsPinch; //状态
|
||||
let IsPinch2 = 1;
|
||||
if (item.threelist.length > 1) {
|
||||
IsPinch2 = item.threelist[1].IsPinch; //状态
|
||||
}
|
||||
if (key == 1) {
|
||||
// 都是全勤的情况
|
||||
if (IsPinch1 == 1 && IsPinch2 == 1) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
} else if (key == 2) {
|
||||
// 存在缺卡 迟到 早退
|
||||
if (['2', '3', '4'].includes(IsPinch1) || ['2', '3', '4'].includes(IsPinch2)) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
} else if (key == 3) {
|
||||
// 出现补卡申请
|
||||
if (IsPinch1 == 5 || IsPinch2 == 5) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
};
|
||||
const getTime = (day, bool, flag = false) => {
|
||||
let time = '';
|
||||
if (state.Daylist && state.Daylist.length) {
|
||||
let arr = state.Daylist;
|
||||
for (let index = 0; index < arr.length; index++) {
|
||||
const item = arr[index];
|
||||
if (item.PrintingDate == day) {
|
||||
if (bool) {
|
||||
time = item.threelist[0].Clock.split(' ')[1];
|
||||
break;
|
||||
} else {
|
||||
if (item.threelist.length > 1) {
|
||||
time = item.threelist[1].Clock.split(' ')[1]; //状态
|
||||
}
|
||||
if (flag) {
|
||||
if (item.threelist.length <= 1) {
|
||||
time = '1';
|
||||
break;
|
||||
}
|
||||
if (item.threelist[1] && item.threelist[1].IsPinch == 4) {
|
||||
//缺卡显示
|
||||
time = '1';
|
||||
} else {
|
||||
//不显示
|
||||
time = '';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return time;
|
||||
};
|
||||
return {
|
||||
proxy,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
onCancel,
|
||||
menuRef,
|
||||
getTime,
|
||||
formRef,
|
||||
calendarRef,
|
||||
selectDate,
|
||||
setFilterDay,
|
||||
...toRefs(state)
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.wxApplet-busAttendance-Detail {
|
||||
width: 100%;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
.label {
|
||||
font-size: 24px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
transform: translateX(-50%);
|
||||
color: #000;
|
||||
font-weight: 500;
|
||||
}
|
||||
.btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.status-detail {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
> div {
|
||||
margin: 0 15px;
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
}
|
||||
.dot1::before,
|
||||
.dot2::before,
|
||||
.dot3::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
display: inline-block;
|
||||
left: -15px;
|
||||
top: 30%;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.dot1::before {
|
||||
background: rgba(29, 111, 233, 1);
|
||||
}
|
||||
.dot2::before {
|
||||
background: rgba(245, 95, 78, 1);
|
||||
}
|
||||
.dot3::before {
|
||||
background: rgba(255, 141, 26, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 700px;
|
||||
.time-cell {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
.status {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
.flex-r {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
margin-top: -14px;
|
||||
}
|
||||
}
|
||||
.flex-c {
|
||||
top: 40%;
|
||||
height: 60%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: baseline;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
padding: 3px 8px;
|
||||
}
|
||||
.normal {
|
||||
color: rgba(64, 158, 255, 1);
|
||||
background: rgba(236, 245, 255, 1);
|
||||
border: 1px solid rgba(64, 158, 255, 1);
|
||||
}
|
||||
.abnormal1 {
|
||||
color: rgba(255, 141, 26, 1);
|
||||
background: rgba(255, 246, 237, 1);
|
||||
border: 1px solid rgba(64, 158, 255, 1);
|
||||
}
|
||||
.abnormal2 {
|
||||
color: rgba(255, 141, 26, 1);
|
||||
background: rgba(255, 246, 237, 1);
|
||||
border: 1px solid rgba(255, 141, 26, 1);
|
||||
}
|
||||
.abnormal3 {
|
||||
color: rgb(245, 95, 78);
|
||||
background: rgba(255, 246, 237, 1);
|
||||
border: 1px solid rgb(245, 95, 78);
|
||||
}
|
||||
}
|
||||
.circle {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
margin: 0 2px;
|
||||
}
|
||||
.status1 {
|
||||
background: rgba(29, 111, 233, 1);
|
||||
}
|
||||
.status2 {
|
||||
background: rgba(245, 95, 78, 1);
|
||||
}
|
||||
.status3 {
|
||||
background: rgba(255, 141, 26, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.flex-c {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
.time {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
> img {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
> span {
|
||||
font-size: 12px;
|
||||
color: rgba(204, 204, 204, 1);
|
||||
padding-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-calendar) {
|
||||
--el-calendar-cell-width: 110px;
|
||||
}
|
||||
:deep(.el-calendar__header) {
|
||||
padding: 12px 5px;
|
||||
}
|
||||
:deep(.el-calendar__body) {
|
||||
max-height: 635px;
|
||||
overflow: auto;
|
||||
}
|
||||
:deep(.el-dialog__body) {
|
||||
max-height: calc(90vh - 0px) !important;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -62,9 +62,9 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出勤(天)" align="center" prop="Attendance" />
|
||||
<el-table-column label="迟到(次)" align="center" prop="LackOfCard" />
|
||||
<el-table-column label="迟到(次)" align="center" prop="BeLate" />
|
||||
<el-table-column label="早退(次)" align="center" prop="LeaveEarly" />
|
||||
<el-table-column label="缺卡(次)" align="center" prop="BeLate" />
|
||||
<el-table-column label="缺卡(次)" align="center" prop="LackOfCard" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="View" @click="handleDetails(scope.row)" v-hasPermi="['project:attendance:edit']">详情</el-button>
|
||||
@ -75,7 +75,7 @@
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 考勤详情对话框 -->
|
||||
<el-dialog v-model="dialog.details" width="1300px">
|
||||
<!-- <el-dialog v-model="dialog.details" width="1300px">
|
||||
<el-calendar ref="calendar" v-model="calendarDay" class="h170 pos-relative">
|
||||
<template #header="{ date }">
|
||||
<span>
|
||||
@ -103,7 +103,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-calendar>
|
||||
</el-dialog>
|
||||
</el-dialog> -->
|
||||
<el-dialog title="导出考勤列表" width="30%" v-model="exportDialogVisible">
|
||||
<el-form :model="exportForm" :rules="rules" ref="formRef" label-width="90px">
|
||||
<el-form-item label="导出时间" prop="years">
|
||||
@ -114,6 +114,7 @@
|
||||
<el-button type="primary" @click="onSubmit">导出</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<detail ref="detailRef"></detail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -126,7 +127,7 @@ import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
const commandstats = ref();
|
||||
import { pcSelectBelowProjectOfPersonnel, getSysProjectTeamList, pcCollectDataForTwoWeeks } from '@/api/project/goUser/index';
|
||||
|
||||
import detail from './component/detail.vue';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { type_of_work } = toRefs<any>(proxy?.useDict('clock_status_type', 'type_of_work'));
|
||||
import type { CalendarInstance } from 'element-plus';
|
||||
@ -136,7 +137,22 @@ const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const exportDialogVisible = ref(false);
|
||||
const nowMonth = computed(() => {
|
||||
// 获取当前日期
|
||||
const today = new Date();
|
||||
|
||||
// 获取年份
|
||||
const year = today.getFullYear();
|
||||
|
||||
// 获取月份(注意:getMonth()返回0-11,所以需要+1)
|
||||
let month = today.getMonth() + 1;
|
||||
|
||||
// 月份补零处理
|
||||
month = month < 10 ? '0' + month : month;
|
||||
|
||||
// 拼接成"YYYY-MM"格式
|
||||
return `${year}-${month}`;
|
||||
});
|
||||
const attendanceList = ref<AttendanceVO[]>([]);
|
||||
const attendanceTwoWeekList = ref<AttendanceTwoWeekVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
@ -187,7 +203,7 @@ const data = reactive<PageData<AttendanceForm, any>>({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
dateStr: undefined,
|
||||
dateStr: nowMonth.value,
|
||||
fuzzyQuery: undefined,
|
||||
projectId: currentProject.value.goId,
|
||||
typeOfWork: undefined,
|
||||
@ -209,7 +225,9 @@ const day = computed(() => (date) => {
|
||||
});
|
||||
//是否打卡
|
||||
const isplayCard = computed(() => (date) => {
|
||||
return calendarList.value.some((item) => item.dateStr == date.day);
|
||||
console.log('🚀 ~ date:', date);
|
||||
|
||||
return calendarList.value.some((item) => item.PrintingDate == date.day);
|
||||
});
|
||||
//打卡时间下标
|
||||
const playCardIdx = computed(() => (date) => {
|
||||
@ -227,7 +245,7 @@ const workFromTime = computed(() => (date) => {
|
||||
|
||||
//考勤状态
|
||||
const attendanceStatus = computed(() => (date) => {
|
||||
return calendarList.value[playCardIdx.value(date)].status;
|
||||
return calendarList.value[playCardIdx.value(date)].Status;
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
@ -328,13 +346,9 @@ const incrementMonth = (dateStr: string, monthsToAdd: number) => {
|
||||
};
|
||||
|
||||
/** 详情按钮操作 */
|
||||
const detailRef = ref<any>();
|
||||
const handleDetails = async (row?: AttendanceVO) => {
|
||||
const res = await listAttendanceMonth({ openid: row?.openid, dateStr: queryParams.value.dateStr });
|
||||
calendarList.value = res.data.list || [];
|
||||
console.log('🚀 ~ handleDetails ~ calendarList.value:', calendarList.value);
|
||||
dialog.details = true;
|
||||
dialog.id = row?.id;
|
||||
dialog.title = row?.userName || '';
|
||||
detailRef.value.openDialog(toRaw(row));
|
||||
};
|
||||
|
||||
const onExport = () => {
|
||||
|
@ -6,7 +6,11 @@
|
||||
<el-row :gutter="20" justify="space-around">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="人脸照">
|
||||
<el-image :src="userDetail?.pacePhoto" style="width: 150px; height: 150px" />
|
||||
<el-image
|
||||
:src="'http://58.17.134.85:8920' + userDetail?.pacePhoto"
|
||||
:preview-src-list="['http://58.17.134.85:8920' + userDetail?.pacePhoto]"
|
||||
style="width: 150px; height: 150px"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@ -154,6 +158,7 @@ const userDetail = ref<ConstructionUserVO>();
|
||||
const getUserDetail = async () => {
|
||||
loading.value = true;
|
||||
const res = await getConstructionUser(props.userId);
|
||||
console.log('🚀 ~ getUserDetail ~ res:', res);
|
||||
if (res.data && res.code === 0) {
|
||||
userDetail.value = res.data;
|
||||
}
|
||||
|
@ -148,7 +148,7 @@
|
||||
<el-table-column label="薪水" align="center" min-width="180">
|
||||
<template #default="scope">
|
||||
<span class="flex justify-center">
|
||||
{{ scope.row.salary ? scope.row.salary : scope.row.standardSalary }}
|
||||
{{ proxy.formatPrice(scope.row.salary ? scope.row.salary : scope.row.standardSalary) }}
|
||||
(<dict-tag :options="wage_measure_unit_type" :value="scope.row.wageMeasureUnit"></dict-tag>)
|
||||
</span>
|
||||
<div class="text-blue text-sm cursor-pointer" @click="openSalaryDialog(scope.row)">{{ scope.row.salary ? '取消变更' : '变更' }}</div>
|
||||
@ -516,7 +516,7 @@ import { AttendanceMonthVO } from '@/api/project/attendance/types';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
|
||||
const calendar = ref<CalendarInstance>();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const { type_of_work, user_sex_type, user_clock_type, user_file_type, user_status_type, wage_measure_unit_type } = toRefs<any>(
|
||||
proxy?.useDict('type_of_work', 'user_sex_type', 'user_clock_type', 'user_file_type', 'user_status_type', 'wage_measure_unit_type')
|
||||
);
|
||||
|
@ -22,7 +22,7 @@
|
||||
<div>
|
||||
<div>
|
||||
<span>租金</span>
|
||||
<span>{{ detailInfo.rentSum / 1000 }} 万元</span>
|
||||
<span>{{ proxy.formatPrice(detailInfo.rentSum) / 1000 }} 万元</span>
|
||||
</div>
|
||||
<el-icon :size="50" color="#3176ff">
|
||||
<Postcard />
|
||||
@ -31,7 +31,7 @@
|
||||
</div>
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-card shadow="never">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="110px">
|
||||
<el-form-item label="对应地块" prop="landBlockId">
|
||||
<el-select v-model="queryParams.landBlockId" clearable placeholder="请选择对应地块">
|
||||
@ -48,15 +48,6 @@
|
||||
<el-form-item label="责任人" prop="responsiblePerson">
|
||||
<el-input v-model="queryParams.responsiblePerson" placeholder="请输入责任人" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预计完成时间" prop="expectedFinishDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.expectedFinishDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择预计完成时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@ -71,36 +62,42 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['land:landTransferLedger:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['land:landTransferLedger:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6"></el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="landTransferLedgerList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="土地类型" align="center" prop="landType" />
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="土地类型" align="center" prop="landTypeName" />
|
||||
<el-table-column label="地块" align="center" prop="landName" />
|
||||
<el-table-column label="进场道路" align="center" prop="roadName" />
|
||||
<el-table-column label="设计面积" align="center" prop="designArea" />
|
||||
<el-table-column label="设计面积(亩)" align="center" prop="designArea" width="180" />
|
||||
<el-table-column label="责任人" align="center" prop="responsiblePerson" />
|
||||
<el-table-column label="预计完成时间" align="center" prop="expectedFinishDate" width="180"> </el-table-column>
|
||||
<el-table-column label="流转状态" align="center" prop="transferStatusName" />
|
||||
<el-table-column label="流转状态" align="center" prop="type" />
|
||||
<el-table-column label="已流转面积(亩)" align="center" prop="transferArea" width="180" />
|
||||
<el-table-column label="不流转数据" align="center" prop="noTrans" width="180" />
|
||||
<el-table-column label="未流转数据" align="center" prop="noTransferAea" width="180" />
|
||||
<el-table-column label="不流转面积(亩)" align="center" prop="noTrans" width="180" />
|
||||
<el-table-column label="未流转面积(亩)" align="center" prop="noTransferAea" width="180" />
|
||||
<el-table-column label="流转比例(%)" align="center" width="180">
|
||||
<template #default="scope">
|
||||
{{ scope.row.transferArea && scope.row.designArea ? ((scope.row.transferArea / scope.row.designArea) * 100).toFixed(2) : '0.00' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="土地租金(元)" align="center" prop="landRentAll" width="180" />
|
||||
<el-table-column label="青苗赔偿(元)" align="center" prop="seedlingCompensationAll" width="180" />
|
||||
<el-table-column label="总金额(元)" align="center" prop="totalAmountAll" width="150" />
|
||||
<el-table-column label="土地租金(元)" align="center" prop="landRentAll" width="180">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.landRentAll) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="青苗赔偿(元)" align="center" prop="seedlingCompensationAll" width="180">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.seedlingCompensationAll) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="总金额(元)" align="center" prop="totalAmountAll" width="150">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalAmountAll) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
|
||||
<el-table-column label="操作" align="center" fixed="right" width="200">
|
||||
<template #default="scope">
|
||||
@ -135,7 +132,7 @@
|
||||
</div>
|
||||
<div class="summary-item transfer-area">
|
||||
<div class="summary-content">
|
||||
<span class="summary-label">已流转面积</span>
|
||||
<span class="summary-label">已流转面积(亩)</span>
|
||||
<span class="summary-value">{{ sonSummaryInfo.totalTransferArea }} 亩</span>
|
||||
</div>
|
||||
<el-icon class="summary-icon" :size="50" color="#3176ff">
|
||||
@ -144,7 +141,7 @@
|
||||
</div>
|
||||
<div class="summary-item non-transfer-area">
|
||||
<div class="summary-content">
|
||||
<span class="summary-label">不流转面积</span>
|
||||
<span class="summary-label">不流转面积(亩)</span>
|
||||
<span class="summary-value">{{ sonSummaryInfo.totalNonTransferArea }} 亩</span>
|
||||
</div>
|
||||
<el-icon class="summary-icon" :size="50" color="#3176ff">
|
||||
@ -153,7 +150,7 @@
|
||||
</div>
|
||||
<div class="summary-item remaining-area">
|
||||
<div class="summary-content">
|
||||
<span class="summary-label">未流转面积</span>
|
||||
<span class="summary-label">未流转面积(亩)</span>
|
||||
<span class="summary-value">{{ sonSummaryInfo.remainingArea }} 亩</span>
|
||||
</div>
|
||||
<el-icon class="summary-icon" :size="50" color="#3176ff">
|
||||
@ -183,9 +180,21 @@
|
||||
<el-table-column label="流转状态" align="center" prop="transferStatusName" />
|
||||
<el-table-column label="已流转面积(亩)" align="center" prop="areaValue" width="180" />
|
||||
<el-table-column label="流转比例(%)" align="center" prop="transferRatio" width="180" />
|
||||
<el-table-column label="土地租金(元)" align="center" prop="landRent" width="180" />
|
||||
<el-table-column label="青苗赔偿(元)" align="center" prop="seedlingCompensation" width="180" />
|
||||
<el-table-column label="总金额(元)" align="center" prop="totalAmount" width="150" />
|
||||
<el-table-column label="土地租金(元)" align="center" prop="landRent" width="180">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.landRent) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="青苗赔偿(元)" align="center" prop="seedlingCompensation" width="180">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.seedlingCompensation) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="总金额(元)" align="center" prop="totalAmount" width="150">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalAmount) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="状态说明" align="center" prop="statusDescription" />
|
||||
<el-table-column label="问题总结" align="center" prop="issueSummary" />
|
||||
<el-table-column label="下一步策略" align="center" prop="nextStrategy" width="180" />
|
||||
@ -195,7 +204,7 @@
|
||||
<!-- 不流转子项 -->
|
||||
<div v-if="sonTransferLedgerList2.length > 0">
|
||||
<h4 style="margin-top: 20px; margin-bottom: 10px; color: #ff6b6b">不流转</h4>
|
||||
<el-table v-loading="sonLoading" :data="sonTransferLedgerList2" @selection-change="handleSonSelectionChange">
|
||||
<el-table v-loading="sonLoading" :data="sonTransferLedgerList2" @selection-change="handleSonSelectionChange" width="100%">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="土地类型" align="center" prop="landTypeName" />
|
||||
<el-table-column label="地块" align="center" prop="landName" />
|
||||
@ -236,8 +245,8 @@
|
||||
</el-dialog>
|
||||
|
||||
<!-- 新增子项对话框 -->
|
||||
<el-dialog draggable :title="sonFormDialog.title" v-model="sonFormDialog.visible" width="600px" append-to-body>
|
||||
<el-form ref="sonLandTransferLedgerFormRef" :model="sonForm" :rules="sonRules" label-width="120px">
|
||||
<el-dialog draggable :title="sonFormDialog.title" v-model="sonFormDialog.visible" width="650px" append-to-body>
|
||||
<el-form ref="sonLandTransferLedgerFormRef" :model="sonForm" :rules="sonRules" label-width="150px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="对应地块" prop="landBlockId">
|
||||
@ -307,7 +316,7 @@
|
||||
<el-form-item label="已流转面积(亩)" prop="areaValue">
|
||||
<el-input v-model="sonForm.areaValue" type="number" placeholder="请输入已流转面积" @input="calcSonTransferRatio" />
|
||||
<div style="color: #ff4d4f; font-size: 12px; margin-top: 4px">
|
||||
{{ sonForm.areaValue && sonForm.transferStatus == '1' ? `提示:已流转面积不能超过设计面积 ${sonForm.designArea} 亩` : '' }}
|
||||
{{ sonForm.areaValue && sonForm.transferStatus == '1' ? `提示:当前剩余${sonSummaryInfo.remainingArea} 亩` : '' }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -340,11 +349,11 @@
|
||||
<el-form-item label="不流转面积(亩)" prop="areaValue">
|
||||
<el-input v-model="sonForm.areaValue" type="number" placeholder="请输入不流转面积" />
|
||||
<div style="color: #ff4d4f; font-size: 12px; margin-top: 4px">
|
||||
{{ sonForm.areaValue && sonForm.transferStatus == '2' ? `提示:不流转面积不能超过设计面积 ${sonForm.designArea} 亩` : '' }}
|
||||
{{ sonForm.areaValue && sonForm.transferStatus == '2' ? `提示:当前剩余 ${sonSummaryInfo.remainingArea} 亩` : '' }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" v-if="sonForm.transferStatus == '2'">
|
||||
<el-col :span="24" v-if="sonForm.transferStatus == '2'" style="">
|
||||
<el-form-item label="不签合同面积(亩)" prop="noContractArea">
|
||||
<el-input v-model="sonForm.noContractArea" type="number" placeholder="请输入不签合同面积" />
|
||||
</el-form-item>
|
||||
@ -526,13 +535,14 @@
|
||||
|
||||
<el-col :span="24" v-if="form.transferStatus == '1'">
|
||||
<el-form-item label="下一步策略" prop="nextStrategy">
|
||||
<el-input v-model="form.nextStrategy" type="textarea" placeholder="请输入内容" /> </el-form-item
|
||||
></el-col>
|
||||
<el-input v-model="form.nextStrategy" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button v-hasPermi="['land:landTransferLedger:add']" :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@ -571,7 +581,7 @@ interface PageData<T, Q> {
|
||||
rules: Record<string, any[]>;
|
||||
}
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
@ -588,7 +598,8 @@ const landBlockList = ref([]);
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const landTransferLedgerFormRef = ref<ElFormInstance>();
|
||||
const enterRoadList = ref([]);
|
||||
const { land_type, transfer_status } = toRefs<any>(proxy?.useDict('land_type', 'transfer_status'));
|
||||
// 字典数据
|
||||
const { land_type, land_transfer_status } = toRefs<any>(proxy?.useDict('land_type', 'land_transfer_status'));
|
||||
|
||||
// 主项弹窗配置
|
||||
const dialog = reactive<DialogOption>({
|
||||
@ -646,14 +657,20 @@ const initFormData: LandTransferLedgerForm = {
|
||||
transferStatus: undefined,
|
||||
statusDescription: undefined,
|
||||
issueSummary: undefined,
|
||||
nextStrategy: undefined
|
||||
nextStrategy: undefined,
|
||||
noContractArea: undefined,
|
||||
noContractReason: undefined,
|
||||
noSurveyArea: undefined,
|
||||
nonTransferReason: undefined
|
||||
};
|
||||
|
||||
// 核心数据响应式对象
|
||||
const data = reactive<PageData<LandTransferLedgerForm, LandTransferLedgerQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
projectId: currentProject.value.id,
|
||||
projectId: currentProject.value?.id,
|
||||
landType: undefined,
|
||||
landBlockId: undefined,
|
||||
enterRoadId: undefined,
|
||||
@ -758,6 +775,16 @@ const sonRules = {
|
||||
projectId: [{ required: true, message: '项目ID不能为空', trigger: 'blur' }],
|
||||
parentId: [{ required: true, message: '父级ID不能为空', trigger: 'blur' }],
|
||||
landType: [{ required: true, message: '土地类型不能为空', trigger: 'change' }],
|
||||
landRent: [{ required: true, message: '土地租金不能为空', trigger: 'blur' }],
|
||||
seedlingCompensation: [{ required: true, message: '青苗赔偿不能为空', trigger: 'blur' }],
|
||||
totalAmount: [{ required: true, message: '总金额不能为空', trigger: 'blur' }],
|
||||
statusDescription: [{ required: true, message: '状态说明不能为空', trigger: 'blur' }],
|
||||
issueSummary: [{ required: true, message: '问题总结不能为空', trigger: 'blur' }],
|
||||
nextStrategy: [{ required: true, message: '下一步策略不能为空', trigger: 'blur' }],
|
||||
noContractArea: [{ required: true, message: '不签约面积不能为空', trigger: 'blur' }],
|
||||
noSurveyArea: [{ required: true, message: '不测量面积不能为空', trigger: 'blur' }],
|
||||
noContractReason: [{ required: true, message: '不签约原因不能为空', trigger: 'blur' }],
|
||||
nonTransferReason: [{ required: true, message: '不流转原因不能为空', trigger: 'blur' }],
|
||||
transferRatio: [
|
||||
{
|
||||
required: true,
|
||||
@ -931,7 +958,6 @@ const getLandBlockList = async () => {
|
||||
|
||||
/** 取消按钮(主项) */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
resetForm();
|
||||
};
|
||||
@ -997,6 +1023,7 @@ const handleAdd = () => {
|
||||
form.value.transferStatus = '0'; // 默认待流转
|
||||
enterRoadList.value = [];
|
||||
dialog.title = '添加项目土地流转台账';
|
||||
dialog.visible = true;
|
||||
};
|
||||
|
||||
/** 查看子项按钮操作(打开子项弹窗时) */
|
||||
@ -1089,9 +1116,10 @@ const submitForm = () => {
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
await getLandBlockList(); // 刷新统计信息
|
||||
} catch (error) {
|
||||
console.error('操作失败:', error);
|
||||
proxy?.$modal.msgError('操作失败,请重试');
|
||||
console.error('提交表单失败:', error);
|
||||
} finally {
|
||||
buttonLoading.value = false;
|
||||
}
|
||||
@ -1159,25 +1187,45 @@ const submitSonForm = () => {
|
||||
/** 删除主项按钮操作 */
|
||||
const handleDelete = async (row?: LandTransferLedgerVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除项目土地流转台账编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
if (!_ids.length) return;
|
||||
|
||||
try {
|
||||
await proxy?.$modal.confirm(`是否确认删除项目土地流转台账编号为"${_ids}"的数据项?`);
|
||||
await delLandTransferLedger(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
await getLandBlockList(); // 刷新统计信息
|
||||
} catch (error) {
|
||||
console.error('删除数据失败:', error);
|
||||
if (error !== 'cancel') {
|
||||
// 排除用户取消确认的情况
|
||||
proxy?.$modal.msgError('删除失败,请重试');
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
// 选择地块
|
||||
const handleLandBlockChange = (val) => {
|
||||
getListRoad();
|
||||
|
||||
/** 选择地块后加载对应道路 */
|
||||
const handleLandBlockChange = async () => {
|
||||
await getListRoad();
|
||||
};
|
||||
/** 查询地块信息列表 */
|
||||
|
||||
/** 查询地块列表 */
|
||||
const getListLand = async () => {
|
||||
try {
|
||||
const res = await listLandBlock({
|
||||
pageNum: 1,
|
||||
pageSize: 10000,
|
||||
projectId: currentProject.value.id
|
||||
projectId: currentProject.value?.id
|
||||
});
|
||||
landBlockList.value = res.rows;
|
||||
} catch (error) {
|
||||
console.error('获取地块列表失败:', error);
|
||||
}
|
||||
};
|
||||
/** 查询进场道路信息列表 */
|
||||
|
||||
/** 查询进场道路列表(按地块筛选) */
|
||||
const getListRoad = async () => {
|
||||
try {
|
||||
// 优先使用子项表单的地块ID,否则使用主项表单的
|
||||
@ -1208,12 +1256,14 @@ const listeningProject = watch(
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
/** 组件卸载时清理监听 */
|
||||
onUnmounted(() => {
|
||||
listeningProject();
|
||||
});
|
||||
|
||||
/** 组件挂载时初始化数据 */
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getListLand();
|
||||
Promise.all([getLandBlockList(), getListLand(), getList()]);
|
||||
});
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="110px">
|
||||
<el-form-item label="对应地块" prop="landBlockId">
|
||||
<el-select v-model="queryParams.landBlockId" clearable placeholder="请选择对应地块">
|
||||
@ -15,31 +15,16 @@
|
||||
<el-form-item label="责任人" prop="responsiblePerson">
|
||||
<el-input v-model="queryParams.responsiblePerson" placeholder="请输入责任人" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预计完成时间" prop="expectedFinishDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.expectedFinishDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择预计完成时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="landTransferLedgerList" @selection-change="handleSelectionChange">
|
||||
<el-table v-loading="loading" :data="landTransferLedgerList">
|
||||
<!-- 二级表格 -->
|
||||
<el-table-column type="expand">
|
||||
<template #default="scope">
|
||||
@ -51,27 +36,39 @@
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="土地类型" align="center" prop="landType" />
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column label="土地类型" align="center" prop="landTypeName" />
|
||||
<el-table-column label="地块" align="center" prop="landName" />
|
||||
<el-table-column label="进场道路" align="center" prop="roadName" />
|
||||
<el-table-column label="设计面积" align="center" prop="designArea" />
|
||||
<el-table-column label="设计面积(亩)" align="center" prop="designArea" width="180" />
|
||||
<el-table-column label="责任人" align="center" prop="responsiblePerson" />
|
||||
<el-table-column label="预计完成时间" align="center" prop="expectedFinishDate" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.expectedFinishDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已流转面积" align="center" prop="transferAea" />
|
||||
<el-table-column label="流转比例" align="center" prop="transferRatio" />
|
||||
<el-table-column label="土地租金" align="center" prop="landRent" />
|
||||
<el-table-column label="青苗赔偿" align="center" prop="seedlingCompensation" />
|
||||
<el-table-column label="总金额" align="center" prop="totalAmount" />
|
||||
<el-table-column label="流转状态" align="center" prop="transferStatus" />
|
||||
<el-table-column label="流转状态" align="center" prop="transferStatusName" />
|
||||
<el-table-column label="已流转面积(亩)" align="center" prop="transferAea" width="180" />
|
||||
<el-table-column label="流转比例(%)" align="center" prop="transferRatio" width="180" />
|
||||
<el-table-column label="土地租金(元)" align="center" prop="landRent" width="180">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.landRent) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="青苗赔偿(元)" align="center" prop="seedlingCompensation" width="180">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.seedlingCompensation) }}
|
||||
</template></el-table-column
|
||||
>
|
||||
<el-table-column label="总金额(元)" align="center" prop="totalAmount" width="150">
|
||||
<template #default="scope">
|
||||
{{ proxy.formatPrice(scope.row.totalAmount) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态说明" align="center" prop="statusDescription" />
|
||||
<el-table-column label="问题总结" align="center" prop="issueSummary" />
|
||||
<el-table-column label="下一步策略" align="center" prop="nextStrategy" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<el-table-column label="下一步策略" align="center" prop="nextStrategy" width="180" />
|
||||
<!-- <el-table-column label="操作" fixed="right" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['land:landTransferLedger:edit']">编辑</el-button>
|
||||
@ -80,7 +77,7 @@
|
||||
<el-button link type="primary" @click="handleDelete(scope.row)" v-hasPermi="['land:landTransferLedger:remove']">删除</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
@ -157,7 +154,7 @@
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button v-hasPermi="['land:landTransferLedger:add']" :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@ -177,7 +174,7 @@ import { listEnterRoad } from '@/api/system/landTransfer/enterRoad';
|
||||
import { LandTransferLedgerVO, LandTransferLedgerQuery, LandTransferLedgerForm } from '@/api/system/landTransfer/landTransferLedger/types';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { listLandBlock } from '@/api/system/landTransfer/landBlock';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
@ -203,7 +200,7 @@ const dialog = reactive<DialogOption>({
|
||||
|
||||
const initFormData: LandTransferLedgerForm = {
|
||||
id: undefined,
|
||||
projectId: currentProject.value.id,
|
||||
projectId: currentProject.value?.id,
|
||||
landType: undefined,
|
||||
landBlockId: undefined,
|
||||
enterRoadId: undefined,
|
||||
@ -225,7 +222,7 @@ const data = reactive<PageData<LandTransferLedgerForm, LandTransferLedgerQuery>>
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
projectId: currentProject.value.id,
|
||||
projectId: currentProject.value?.id,
|
||||
landType: undefined,
|
||||
landBlockId: undefined,
|
||||
enterRoadId: undefined,
|
||||
@ -344,18 +341,18 @@ const getListLand = async () => {
|
||||
const res = await listLandBlock({
|
||||
pageNum: 1,
|
||||
pageSize: 10000,
|
||||
projectId: currentProject.value.id
|
||||
projectId: currentProject.value?.id
|
||||
});
|
||||
landBlockList.value = res.rows;
|
||||
};
|
||||
/** 查询进场道路信息列表 */
|
||||
const getListRoad = async () => {
|
||||
const res = await listEnterRoad({ pageNum: 1, pageSize: 10000, projectId: currentProject.value.id, landBlockId: form.value.landBlockId });
|
||||
const res = await listEnterRoad({ pageNum: 1, pageSize: 10000, projectId: currentProject.value?.id, landBlockId: form.value.landBlockId });
|
||||
enterRoadList.value = res.rows;
|
||||
};
|
||||
//监听项目id刷新数据
|
||||
const listeningProject = watch(
|
||||
() => currentProject.value.id,
|
||||
() => currentProject.value?.id,
|
||||
(nid, oid) => {
|
||||
queryParams.value.projectId = nid;
|
||||
getListLand();
|
||||
|
@ -93,7 +93,7 @@
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="projectTeamMemberFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="施工人员" prop="memberId" v-if="!form.id">
|
||||
<el-select v-model="form.memberId" clearable placeholder="请选择人员" filterable>
|
||||
<el-select v-model="form.memberId" clearable placeholder="请选择人员" remote :remote-method="getUserListNotInTeam" filterable>
|
||||
<el-option v-for="item in userNotInTeamOpt" :key="item.value" :label="item.label" :value="item.value" />
|
||||
<pagination
|
||||
size="small"
|
||||
@ -188,7 +188,16 @@ const userStore = useUserStoreHook();
|
||||
// 从 store 中获取项目列表和当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { user_post_type } = toRefs<any>(proxy?.useDict('user_post_type'));
|
||||
const user_post_type = ref([
|
||||
{
|
||||
label: '普通员工',
|
||||
value: '4'
|
||||
},
|
||||
{
|
||||
label: '班组长',
|
||||
value: '10'
|
||||
}
|
||||
]);
|
||||
const memberStatus = ref(false);
|
||||
interface Props {
|
||||
projectTeamVo: ProjectTeamVO;
|
||||
@ -262,6 +271,7 @@ const cancel = () => {
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
projectTeamMemberFormRef.value?.resetFields();
|
||||
userQueryParams.value.userName = '';
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
@ -298,13 +308,15 @@ const userQueryParams = ref<ConstructionUserQuery>({
|
||||
pageSize: 10,
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
projectId: currentProject.value.goId
|
||||
projectId: currentProject.value.goId,
|
||||
userName: ''
|
||||
});
|
||||
|
||||
// 获取不在当前班组的成员
|
||||
const getUserListNotInTeam = async () => {
|
||||
const getUserListNotInTeam = async (query?: string) => {
|
||||
loading.value = true;
|
||||
console.log(currentProject.value.goId);
|
||||
console.log('query', query, userQueryParams.value);
|
||||
if (query && !query.page) userQueryParams.value.userName = query;
|
||||
|
||||
const res = await listConstructionUser({ ...userQueryParams.value, notTeamId: props.projectTeamVo.id });
|
||||
userNotInTeamOpt.value = res.data.list.map((user: ConstructionUserVO) => ({
|
||||
|
@ -6,7 +6,11 @@
|
||||
<el-row :gutter="20" justify="space-around">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="人脸照">
|
||||
<el-image :src="'http://58.17.134.85:8919' + userDetail?.pacePhoto" style="width: 150px; height: 150px" />
|
||||
<el-image
|
||||
:src="'http://58.17.134.85:8920' + userDetail?.pacePhoto"
|
||||
:preview-src-list="['http://58.17.134.85:8920' + userDetail?.pacePhoto]"
|
||||
style="width: 150px; height: 150px"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@ -154,9 +158,11 @@ const userDetail = ref<ConstructionUserVO>();
|
||||
const getUserDetail = async () => {
|
||||
loading.value = true;
|
||||
const res = await getDetails(props.userId);
|
||||
console.log('🚀 ~ getUserDetail ~ res:', res);
|
||||
if (res.data && res.code === 0) {
|
||||
userDetail.value = res.data;
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
|