新增:每月1日自动生成保养计划
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
VITE_APP_NAME=后台管理系统
|
VITE_APP_NAME=后台管理系统
|
||||||
#VITE_API_URL=http://127.0.0.1:10041/api
|
VITE_API_URL=http://127.0.0.1:10041/api
|
||||||
VITE_API_URL=http://1.14.159.185:10041/api
|
#VITE_API_URL=http://1.14.159.185:10041/api
|
||||||
|
|||||||
108
src/api/tower/security-record/index.ts
Normal file
108
src/api/tower/security-record/index.ts
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import type { ApiResult, PageResult } from '@/api';
|
||||||
|
import type {
|
||||||
|
SecurityRecord,
|
||||||
|
SecurityRecordParam
|
||||||
|
} from '@/api/tower/security-record/model';
|
||||||
|
/**
|
||||||
|
* 分页查询仓库
|
||||||
|
*/
|
||||||
|
export async function pageSecurityRecord(params: SecurityRecordParam) {
|
||||||
|
const res = await request.get<ApiResult<PageResult<SecurityRecord>>>(
|
||||||
|
'/tower/tower-security-record/page',
|
||||||
|
{
|
||||||
|
params
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询仓库列表
|
||||||
|
*/
|
||||||
|
export async function listSecurityRecord(params?: SecurityRecordParam) {
|
||||||
|
const res = await request.get<ApiResult<SecurityRecord[]>>(
|
||||||
|
'/tower/tower-security-record',
|
||||||
|
{
|
||||||
|
params
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.data.code === 0 && res.data.data) {
|
||||||
|
return res.data.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加仓库
|
||||||
|
*/
|
||||||
|
export async function addSecurityRecord(data: SecurityRecord) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security-record',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改仓库
|
||||||
|
*/
|
||||||
|
export async function updateSecurityRecord(data: SecurityRecord) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security-record',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定仓库
|
||||||
|
*/
|
||||||
|
export async function bindSecurityRecord(data: SecurityRecord) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security-record/bind',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除仓库
|
||||||
|
*/
|
||||||
|
export async function removeSecurityRecord(id?: number) {
|
||||||
|
const res = await request.delete<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security-record/' + id
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除仓库
|
||||||
|
*/
|
||||||
|
export async function removeBatchSecurityRecord(data: (number | undefined)[]) {
|
||||||
|
const res = await request.delete<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security-record/batch',
|
||||||
|
{
|
||||||
|
data
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
31
src/api/tower/security-record/model/index.ts
Normal file
31
src/api/tower/security-record/model/index.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import type { PageParam } from '@/api';
|
||||||
|
|
||||||
|
export interface SecurityRecord {
|
||||||
|
securityRecordId?: number;
|
||||||
|
projectName?: string;
|
||||||
|
projectId?: number;
|
||||||
|
securityCode?: string;
|
||||||
|
regionName?: string;
|
||||||
|
longitude?: string;
|
||||||
|
latitude?: string;
|
||||||
|
country?: string;
|
||||||
|
province?: string;
|
||||||
|
city?: string;
|
||||||
|
region?: string;
|
||||||
|
address?: string;
|
||||||
|
status?: number;
|
||||||
|
userId?: number;
|
||||||
|
comments?: string;
|
||||||
|
sortNumber?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索条件
|
||||||
|
*/
|
||||||
|
export interface SecurityRecordParam extends PageParam {
|
||||||
|
securityId?: number;
|
||||||
|
projectId?: number;
|
||||||
|
projectName?: string;
|
||||||
|
status?: number;
|
||||||
|
keywords?: string;
|
||||||
|
}
|
||||||
105
src/api/tower/security/index.ts
Normal file
105
src/api/tower/security/index.ts
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import type { ApiResult, PageResult } from '@/api';
|
||||||
|
import type { Security, SecurityParam } from '@/api/tower/security/model';
|
||||||
|
/**
|
||||||
|
* 分页查询仓库
|
||||||
|
*/
|
||||||
|
export async function pageSecurity(params: SecurityParam) {
|
||||||
|
const res = await request.get<ApiResult<PageResult<Security>>>(
|
||||||
|
'/tower/tower-security/page',
|
||||||
|
{
|
||||||
|
params
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询仓库列表
|
||||||
|
*/
|
||||||
|
export async function listSecurity(params?: SecurityParam) {
|
||||||
|
const res = await request.get<ApiResult<Security[]>>(
|
||||||
|
'/tower/tower-security',
|
||||||
|
{
|
||||||
|
params
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.data.code === 0 && res.data.data) {
|
||||||
|
return res.data.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加仓库
|
||||||
|
*/
|
||||||
|
export async function addSecurity(data: Security) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改仓库
|
||||||
|
*/
|
||||||
|
export async function updateSecurity(data: Security) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定仓库
|
||||||
|
*/
|
||||||
|
export async function bindSecurity(data: Security) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security/bind',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除仓库
|
||||||
|
*/
|
||||||
|
export async function removeSecurity(id?: number) {
|
||||||
|
const res = await request.delete<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security/' + id
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除仓库
|
||||||
|
*/
|
||||||
|
export async function removeBatchSecurity(data: (number | undefined)[]) {
|
||||||
|
const res = await request.delete<ApiResult<unknown>>(
|
||||||
|
'/tower/tower-security/batch',
|
||||||
|
{
|
||||||
|
data
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
31
src/api/tower/security/model/index.ts
Normal file
31
src/api/tower/security/model/index.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import type { PageParam } from '@/api';
|
||||||
|
|
||||||
|
export interface Security {
|
||||||
|
securityId?: number;
|
||||||
|
projectName?: string;
|
||||||
|
projectId?: number;
|
||||||
|
securityCode?: string;
|
||||||
|
regionName?: string;
|
||||||
|
longitude?: string;
|
||||||
|
latitude?: string;
|
||||||
|
country?: string;
|
||||||
|
province?: string;
|
||||||
|
city?: string;
|
||||||
|
region?: string;
|
||||||
|
address?: string;
|
||||||
|
status?: number;
|
||||||
|
userId?: number;
|
||||||
|
comments?: string;
|
||||||
|
sortNumber?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索条件
|
||||||
|
*/
|
||||||
|
export interface SecurityParam extends PageParam {
|
||||||
|
securityId?: number;
|
||||||
|
projectId?: number;
|
||||||
|
projectName?: string;
|
||||||
|
status?: number;
|
||||||
|
keywords?: string;
|
||||||
|
}
|
||||||
@@ -54,12 +54,8 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="其他说明备注">
|
<a-form-item label="其他说明备注">
|
||||||
<a-input
|
<a-input allow-clear v-model:value="form.remark" />
|
||||||
allow-clear
|
|
||||||
v-model:value="form.remark"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :md="8" :sm="24" :xs="24">
|
<a-col :md="8" :sm="24" :xs="24">
|
||||||
<a-form-item label="出租单位" v-bind="validateInfos.companyId">
|
<a-form-item label="出租单位" v-bind="validateInfos.companyId">
|
||||||
@@ -88,8 +84,14 @@
|
|||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="合同存档">
|
<a-form-item label="合同存档">
|
||||||
<a-switch :checked="form.isInStock" :checked-value="1" :un-checked-value="0" checked-children="已归档"
|
<a-switch
|
||||||
un-checked-children="未归档" @change="changeInStock" />
|
:checked="form.isInStock"
|
||||||
|
:checked-value="1"
|
||||||
|
:un-checked-value="0"
|
||||||
|
checked-children="已归档"
|
||||||
|
un-checked-children="未归档"
|
||||||
|
@change="changeInStock"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :md="8" :sm="24" :xs="24">
|
<a-col :md="8" :sm="24" :xs="24">
|
||||||
@@ -121,8 +123,14 @@
|
|||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="是否自动结算">
|
<a-form-item label="是否自动结算">
|
||||||
<a-switch :checked="form.autoSettle" :checked-value="1" :un-checked-value="0" checked-children="是"
|
<a-switch
|
||||||
un-checked-children="否" @change="changeAutoSettle" />
|
:checked="form.autoSettle"
|
||||||
|
:checked-value="1"
|
||||||
|
:un-checked-value="0"
|
||||||
|
checked-children="是"
|
||||||
|
un-checked-children="否"
|
||||||
|
@change="changeAutoSettle"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -139,13 +147,21 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="欠收金额汇总">
|
<a-form-item label="欠收金额汇总">
|
||||||
<p style="margin-bottom: 0">{{ form.totalSettleAmount - form.totalIncomeAmount }}</p>
|
<p style="margin-bottom: 0">{{
|
||||||
|
form.totalSettleAmount - form.totalIncomeAmount
|
||||||
|
}}</p>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
<div class="flex flex-col justify-start justify-start"
|
<div
|
||||||
style="padding: 1rem 0;border-top: 1px solid #dcdfe6; border-bottom: 1px solid #dcdfe6">
|
class="flex flex-col justify-start justify-start"
|
||||||
|
style="
|
||||||
|
padding: 1rem 0;
|
||||||
|
border-top: 1px solid #dcdfe6;
|
||||||
|
border-bottom: 1px solid #dcdfe6;
|
||||||
|
"
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<p>合同电子存档</p>
|
<p>合同电子存档</p>
|
||||||
<div class="flex justify-start">
|
<div class="flex justify-start">
|
||||||
@@ -164,8 +180,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-start items-center"
|
<div
|
||||||
style="padding: 1rem 0;border-top: 1px solid #dcdfe6;">
|
class="flex justify-start items-center"
|
||||||
|
style="padding: 1rem 0; border-top: 1px solid #dcdfe6"
|
||||||
|
>
|
||||||
<div class="flex justify-start items-center">
|
<div class="flex justify-start items-center">
|
||||||
<unordered-list-outlined />
|
<unordered-list-outlined />
|
||||||
<span>合同签订设备清单</span>
|
<span>合同签订设备清单</span>
|
||||||
@@ -211,62 +229,119 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<div style="min-height: 10rem">
|
<div style="min-height: 10rem">
|
||||||
<div class=" p-05 flex justify-center items-center" v-if="contractEquipmentList.length === 0">
|
<div
|
||||||
|
class="p-05 flex justify-center items-center"
|
||||||
|
v-if="contractEquipmentList.length === 0"
|
||||||
|
>
|
||||||
<span class="text-grey">暂无数据</span>
|
<span class="text-grey">暂无数据</span>
|
||||||
</div>
|
</div>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<a-row class="text-center" v-for="(item, index) in contractEquipmentList"
|
<a-row
|
||||||
:key="index">
|
class="text-center"
|
||||||
|
v-for="(item, index) in contractEquipmentList"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
<a-col :span="3" class="p-05 border-r-white">
|
<a-col :span="3" class="p-05 border-r-white">
|
||||||
<a-select placeholder="必选项" style="width: 100%" size="small" @change="changeEquipment($event, index)"
|
<a-select
|
||||||
v-model:value="contractEquipmentList[index].equipmentId">
|
placeholder="必选项"
|
||||||
<a-select-option v-for="(item, index) in equipmentList" :key="index" :value="item.equipmentId">
|
style="width: 100%"
|
||||||
|
size="small"
|
||||||
|
@change="changeEquipment($event, index)"
|
||||||
|
v-model:value="contractEquipmentList[index].equipmentId"
|
||||||
|
>
|
||||||
|
<a-select-option
|
||||||
|
v-for="(item, index) in equipmentList"
|
||||||
|
:key="index"
|
||||||
|
:value="item.equipmentId"
|
||||||
|
>
|
||||||
{{ item.name }}({{ item.model }})
|
{{ item.name }}({{ item.model }})
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="2" class="p-05 border-r-white">
|
<a-col :span="2" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].equipmentModel" size="small" readonly/>
|
<a-input
|
||||||
|
v-model:value="contractEquipmentList[index].equipmentModel"
|
||||||
|
size="small"
|
||||||
|
readonly
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="3" class="p-05 border-r-white">
|
<a-col :span="3" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].filingNo" size="small" readonly/>
|
<a-input
|
||||||
|
v-model:value="contractEquipmentList[index].filingNo"
|
||||||
|
size="small"
|
||||||
|
readonly
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="2" class="p-05 border-r-white">
|
<a-col :span="2" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].num" size="small" placeholder="必填项" type="number">
|
<a-input
|
||||||
|
v-model:value="contractEquipmentList[index].num"
|
||||||
|
size="small"
|
||||||
|
placeholder="必填项"
|
||||||
|
type="number"
|
||||||
|
>
|
||||||
<template #suffix>台</template>
|
<template #suffix>台</template>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="2" class="p-05 border-r-white">
|
<a-col :span="2" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].planRentMonth" size="small" placeholder="必填项"
|
<a-input
|
||||||
type="number" />
|
v-model:value="contractEquipmentList[index].planRentMonth"
|
||||||
|
size="small"
|
||||||
|
placeholder="必填项"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="2" class="p-05 border-r-white">
|
<a-col :span="2" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].rentAmount" size="small" placeholder="必填项"
|
<a-input
|
||||||
type="number" />
|
v-model:value="contractEquipmentList[index].rentAmount"
|
||||||
|
size="small"
|
||||||
|
placeholder="必填项"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="2" class="p-05 border-r-white">
|
<a-col :span="2" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].inOutAmount" size="small" placeholder="必填项"
|
<a-input
|
||||||
type="number" />
|
v-model:value="contractEquipmentList[index].inOutAmount"
|
||||||
|
size="small"
|
||||||
|
placeholder="必填项"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="2" class="p-05 border-r-white">
|
<a-col :span="2" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].workerAmount" size="small" placeholder="必填项"
|
<a-input
|
||||||
type="number" />
|
v-model:value="contractEquipmentList[index].workerAmount"
|
||||||
|
size="small"
|
||||||
|
placeholder="必填项"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="2" class="p-05 border-r-white">
|
<a-col :span="2" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].otherAmount" size="small" placeholder="必填项"
|
<a-input
|
||||||
type="number" />
|
v-model:value="contractEquipmentList[index].otherAmount"
|
||||||
|
size="small"
|
||||||
|
placeholder="必填项"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="2" class="p-05 border-r-white">
|
<a-col :span="2" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].preBuryAmount" size="small"
|
<a-input
|
||||||
type="number" />
|
v-model:value="contractEquipmentList[index].preBuryAmount"
|
||||||
|
size="small"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="1" class="p-05 border-r-white">
|
<a-col :span="1" class="p-05 border-r-white">
|
||||||
<a-input v-model:value="contractEquipmentList[index].remark" size="small" placeholder="可选项" />
|
<a-input
|
||||||
|
v-model:value="contractEquipmentList[index].remark"
|
||||||
|
size="small"
|
||||||
|
placeholder="可选项"
|
||||||
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="1" class="p-05">
|
<a-col :span="1" class="p-05">
|
||||||
<div class="flex justify-center items-center">
|
<div class="flex justify-center items-center">
|
||||||
<close-circle-outlined style="font-size: 1.5rem; color: pink;cursor: pointer"
|
<close-circle-outlined
|
||||||
@click.native="delEquipment(index)" />
|
style="font-size: 1.5rem; color: pink; cursor: pointer"
|
||||||
|
@click.native="delEquipment(index)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -285,39 +360,46 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, watch, computed } from "vue";
|
import { ref, reactive, watch, computed } from 'vue';
|
||||||
import { Form, message, UploadFile } from "ant-design-vue";
|
import { Form, message, UploadFile } from 'ant-design-vue';
|
||||||
import { assignObject } from "ele-admin-pro";
|
import { assignObject } from 'ele-admin-pro';
|
||||||
import { updateContract, addContract } from "@/api/tower/contract";
|
import { updateContract, addContract } from '@/api/tower/contract';
|
||||||
import { useUserStore } from "@/store/modules/user";
|
import { useUserStore } from '@/store/modules/user';
|
||||||
import { Contract } from "@/api/tower/contract/model";
|
import { Contract } from '@/api/tower/contract/model';
|
||||||
import dayjs from "dayjs";
|
import dayjs from 'dayjs';
|
||||||
import { ContractFile } from "@/api/tower/contractFile/model";
|
import { ContractFile } from '@/api/tower/contractFile/model';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
UnorderedListOutlined,
|
UnorderedListOutlined,
|
||||||
CloseCircleOutlined, UploadOutlined
|
CloseCircleOutlined,
|
||||||
} from "@ant-design/icons-vue";
|
UploadOutlined
|
||||||
import { ContractEquipment } from "@/api/tower/contractEquipment/model";
|
} from '@ant-design/icons-vue';
|
||||||
import { TowerModel } from "@/api/tower/model/model";
|
import { ContractEquipment } from '@/api/tower/contractEquipment/model';
|
||||||
import { listTowerModel } from "@/api/tower/model";
|
import { TowerModel } from '@/api/tower/model/model';
|
||||||
import { addBatchContractFile, listContractFile } from "@/api/tower/contractFile";
|
import { listTowerModel } from '@/api/tower/model';
|
||||||
import { addBatchContractEquipment, listContractEquipment } from "@/api/tower/contractEquipment";
|
import {
|
||||||
import { Company } from "@/api/system/company/model";
|
addBatchContractFile,
|
||||||
import { Customer } from "@/api/oa/customer/model";
|
listContractFile
|
||||||
import { listTowerEquipment } from "@/api/tower/equipment";
|
} from '@/api/tower/contractFile';
|
||||||
import { TowerEquipment } from "@/api/tower/equipment/model";
|
import {
|
||||||
import { TOKEN_STORE_NAME } from "@/config/setting";
|
addBatchContractEquipment,
|
||||||
import { FileItem } from "ele-admin-pro/es/ele-file-list/types";
|
listContractEquipment
|
||||||
import { Equipment } from "@/api/apps/equipment/model";
|
} from '@/api/tower/contractEquipment';
|
||||||
|
import { Company } from '@/api/system/company/model';
|
||||||
|
import { Customer } from '@/api/oa/customer/model';
|
||||||
|
import { listTowerEquipment } from '@/api/tower/equipment';
|
||||||
|
import { TowerEquipment } from '@/api/tower/equipment/model';
|
||||||
|
import { TOKEN_STORE_NAME } from '@/config/setting';
|
||||||
|
import { FileItem } from 'ele-admin-pro/es/ele-file-list/types';
|
||||||
|
import { Equipment } from '@/api/apps/equipment/model';
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
// 当前用户信息
|
// 当前用户信息
|
||||||
const loginUser = computed(() => userStore.info ?? {});
|
const loginUser = computed(() => userStore.info ?? {});
|
||||||
const token = localStorage.getItem(TOKEN_STORE_NAME);
|
const token = localStorage.getItem(TOKEN_STORE_NAME);
|
||||||
|
|
||||||
const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
const now = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
|
||||||
// 是否是修改
|
// 是否是修改
|
||||||
const isUpdate = ref(false);
|
const isUpdate = ref(false);
|
||||||
@@ -330,8 +412,8 @@ const props = defineProps<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "done"): void;
|
(e: 'done'): void;
|
||||||
(e: "update:visible", visible: boolean): void;
|
(e: 'update:visible', visible: boolean): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 提交状态
|
// 提交状态
|
||||||
@@ -345,11 +427,11 @@ const form = reactive<Contract>({
|
|||||||
projectId: undefined,
|
projectId: undefined,
|
||||||
companyId: undefined,
|
companyId: undefined,
|
||||||
customerId: undefined,
|
customerId: undefined,
|
||||||
customerContact: "",
|
customerContact: '',
|
||||||
contactNumber: "",
|
contactNumber: '',
|
||||||
signDate: "",
|
signDate: '',
|
||||||
startDate: "",
|
startDate: '',
|
||||||
endDate: "",
|
endDate: '',
|
||||||
contractAmount: undefined,
|
contractAmount: undefined,
|
||||||
contactAgreeAmount: undefined,
|
contactAgreeAmount: undefined,
|
||||||
totalSettleAmount: 0,
|
totalSettleAmount: 0,
|
||||||
@@ -357,13 +439,13 @@ const form = reactive<Contract>({
|
|||||||
isInStock: 0,
|
isInStock: 0,
|
||||||
autoSettle: 0,
|
autoSettle: 0,
|
||||||
payRate: undefined,
|
payRate: undefined,
|
||||||
remark: "",
|
remark: '',
|
||||||
fileList: "[]"
|
fileList: '[]'
|
||||||
});
|
});
|
||||||
|
|
||||||
/* 更新visible */
|
/* 更新visible */
|
||||||
const updateVisible = (value: boolean) => {
|
const updateVisible = (value: boolean) => {
|
||||||
emit("update:visible", value);
|
emit('update:visible', value);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
@@ -371,8 +453,8 @@ const rules = reactive({
|
|||||||
projectId: [
|
projectId: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: "请选择项目",
|
message: '请选择项目',
|
||||||
trigger: "blur"
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
// contactNumber: [
|
// contactNumber: [
|
||||||
@@ -385,20 +467,20 @@ const rules = reactive({
|
|||||||
companyId: [
|
companyId: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: "请选择出租单位",
|
message: '请选择出租单位',
|
||||||
trigger: "blur"
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
customerId: [
|
customerId: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: "请选择承租单位",
|
message: '请选择承租单位',
|
||||||
trigger: "blur"
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectName = ref<string>("");
|
const projectName = ref<string>('');
|
||||||
const chooseProject = (res) => {
|
const chooseProject = (res) => {
|
||||||
// console.log(res)
|
// console.log(res)
|
||||||
projectName.value = res.projectName;
|
projectName.value = res.projectName;
|
||||||
@@ -417,7 +499,7 @@ const chooseCompany = (res: Company) => {
|
|||||||
form.companyId = res.companyId;
|
form.companyId = res.companyId;
|
||||||
};
|
};
|
||||||
|
|
||||||
const customerName = ref<string>("");
|
const customerName = ref<string>('');
|
||||||
const chooseCustomer = (res: Customer) => {
|
const chooseCustomer = (res: Customer) => {
|
||||||
customerName.value = res.name;
|
customerName.value = res.name;
|
||||||
form.customerId = res.customerId;
|
form.customerId = res.customerId;
|
||||||
@@ -432,7 +514,6 @@ const changeAutoSettle = (checked) => {
|
|||||||
form.autoSettle = checked;
|
form.autoSettle = checked;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const fileList = ref<FileItem[]>([]);
|
const fileList = ref<FileItem[]>([]);
|
||||||
|
|
||||||
interface FileInfo {
|
interface FileInfo {
|
||||||
@@ -453,16 +534,22 @@ const onFileUpload = (info: FileInfo) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const contractFileList = ref<ContractFile[]>([]);
|
const contractFileList = ref<ContractFile[]>([]);
|
||||||
const uploadFile = path => {
|
const uploadFile = (path) => {
|
||||||
contractFileList.value.push({ path, contractId: 0, userId: loginUser.value.userId });
|
contractFileList.value.push({
|
||||||
|
path,
|
||||||
|
contractId: 0,
|
||||||
|
userId: loginUser.value.userId
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const delFile = index => {
|
const delFile = (index) => {
|
||||||
contractFileList.value.splice(index, 1);
|
contractFileList.value.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getContractFileList = async () => {
|
const getContractFileList = async () => {
|
||||||
contractFileList.value = await listContractFile({ contractId: props.data?.contractId });
|
contractFileList.value = await listContractFile({
|
||||||
|
contractId: props.data?.contractId
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const equipmentList = ref<TowerEquipment[]>([]);
|
const equipmentList = ref<TowerEquipment[]>([]);
|
||||||
@@ -477,14 +564,16 @@ const getEquipmentModelList = async () => {
|
|||||||
|
|
||||||
const contractEquipmentList = ref<ContractEquipment[]>([]);
|
const contractEquipmentList = ref<ContractEquipment[]>([]);
|
||||||
const getContractEquipmentList = async () => {
|
const getContractEquipmentList = async () => {
|
||||||
contractEquipmentList.value = await listContractEquipment({ contractId: props.data?.contractId });
|
contractEquipmentList.value = await listContractEquipment({
|
||||||
|
contractId: props.data?.contractId
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const chooseEquipmentName = (res, index) => {
|
const chooseEquipmentName = (res, index) => {
|
||||||
contractEquipmentList.value[index].equipmentName = res.name;
|
contractEquipmentList.value[index].equipmentName = res.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const delEquipment = index => {
|
const delEquipment = (index) => {
|
||||||
contractEquipmentList.value.splice(index, 1);
|
contractEquipmentList.value.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -493,8 +582,8 @@ const addEquipment = () => {
|
|||||||
contractEquipmentId: null,
|
contractEquipmentId: null,
|
||||||
contractId: null,
|
contractId: null,
|
||||||
equipmentId: undefined,
|
equipmentId: undefined,
|
||||||
equipmentName: "",
|
equipmentName: '',
|
||||||
equipmentModel: "",
|
equipmentModel: '',
|
||||||
num: null,
|
num: null,
|
||||||
planRentMonth: null,
|
planRentMonth: null,
|
||||||
rentAmount: null,
|
rentAmount: null,
|
||||||
@@ -514,7 +603,7 @@ const save = () => {
|
|||||||
.then(async () => {
|
.then(async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
// 去除空格
|
// 去除空格
|
||||||
form.contactNumber = form.contactNumber?.replace(/\s*/g, "");
|
form.contactNumber = form.contactNumber?.replace(/\s*/g, '');
|
||||||
// 判断权限
|
// 判断权限
|
||||||
// if (loginUser.value.roles?.[0].roleCode != 'admin'){
|
// if (loginUser.value.roles?.[0].roleCode != 'admin'){
|
||||||
// form.status = '1';
|
// form.status = '1';
|
||||||
@@ -525,42 +614,42 @@ const save = () => {
|
|||||||
for (let i = 0; i < contractEquipmentList.value.length; i++) {
|
for (let i = 0; i < contractEquipmentList.value.length; i++) {
|
||||||
if (!contractEquipmentList.value[i].equipmentId) {
|
if (!contractEquipmentList.value[i].equipmentId) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.error("请选择设备");
|
message.error('请选择设备');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!contractEquipmentList.value[i].equipmentModel) {
|
if (!contractEquipmentList.value[i].equipmentModel) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.error("请选择设备型号");
|
message.error('请选择设备型号');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!contractEquipmentList.value[i].num) {
|
if (!contractEquipmentList.value[i].num) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.error("请输入签订数量");
|
message.error('请输入签订数量');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (contractEquipmentList.value[i].planRentMonth === null) {
|
if (contractEquipmentList.value[i].planRentMonth === null) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.error("请输入计划租期");
|
message.error('请输入计划租期');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (contractEquipmentList.value[i].rentAmount === null) {
|
if (contractEquipmentList.value[i].rentAmount === null) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.error("请输入租金");
|
message.error('请输入租金');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (contractEquipmentList.value[i].inOutAmount === null) {
|
if (contractEquipmentList.value[i].inOutAmount === null) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.error("请输入进退场费");
|
message.error('请输入进退场费');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (contractEquipmentList.value[i].workerAmount === null) {
|
if (contractEquipmentList.value[i].workerAmount === null) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.error("请输入劳务费用");
|
message.error('请输入劳务费用');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (contractEquipmentList.value[i].otherAmount === null) {
|
if (contractEquipmentList.value[i].otherAmount === null) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.error("请输入其他费用");
|
message.error('请输入其他费用');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -572,15 +661,14 @@ const save = () => {
|
|||||||
});
|
});
|
||||||
const contractId = res?.data;
|
const contractId = res?.data;
|
||||||
// if (contractFileList.value.length > 0) await saveFileList(contractId);
|
// if (contractFileList.value.length > 0) await saveFileList(contractId);
|
||||||
if (contractEquipmentList.value.length > 0) await saveEquipmentList(contractId);
|
if (contractEquipmentList.value.length > 0)
|
||||||
|
await saveEquipmentList(contractId);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
message.success(res?.message);
|
message.success(res?.message);
|
||||||
updateVisible(false);
|
updateVisible(false);
|
||||||
emit("done");
|
emit('done');
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveFileList = async (contractId) => {
|
const saveFileList = async (contractId) => {
|
||||||
@@ -598,11 +686,13 @@ const saveEquipmentList = async (contractId) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const changeEquipment = (equipmentId, index) => {
|
const changeEquipment = (equipmentId, index) => {
|
||||||
const equip = equipmentList.value.filter(item => item.equipmentId === equipmentId)[0]
|
const equip = equipmentList.value.filter(
|
||||||
console.log(equip)
|
(item) => item.equipmentId === equipmentId
|
||||||
contractEquipmentList.value[index].equipmentModel = equip.model
|
)[0];
|
||||||
contractEquipmentList.value[index].filingNo = equip.filingNo
|
console.log(equip);
|
||||||
}
|
contractEquipmentList.value[index].equipmentModel = equip.model;
|
||||||
|
contractEquipmentList.value[index].filingNo = equip.filingNo;
|
||||||
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.visible,
|
() => props.visible,
|
||||||
@@ -626,7 +716,7 @@ watch(
|
|||||||
isUpdate.value = false;
|
isUpdate.value = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
projectName.value = customerName.value = companyName.value = "";
|
projectName.value = customerName.value = companyName.value = '';
|
||||||
contractFileList.value = [];
|
contractFileList.value = [];
|
||||||
fileList.value = [];
|
fileList.value = [];
|
||||||
resetFields();
|
resetFields();
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<template xmlns="">
|
||||||
|
<ele-modal
|
||||||
|
:width="500"
|
||||||
|
:visible="visible"
|
||||||
|
:confirm-loading="loading"
|
||||||
|
:title="isUpdate ? '修改保养计划' : '新建保养计划'"
|
||||||
|
:body-style="{ paddingBottom: '8px' }"
|
||||||
|
@update:visible="updateVisible"
|
||||||
|
@ok="save"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="styleResponsive ? { md: 6, sm: 6, xs: 24 } : { flex: '90px' }"
|
||||||
|
:wrapper-col="
|
||||||
|
styleResponsive ? { md: 18, sm: 20, xs: 24 } : { flex: '1' }
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col
|
||||||
|
v-bind="styleResponsive ? { md: 22, sm: 24, xs: 24 } : { span: 12 }"
|
||||||
|
>
|
||||||
|
<a-form-item label="项目名称" name="name">
|
||||||
|
<ProjectSelectModel
|
||||||
|
:placeholder="`请选择项目`"
|
||||||
|
v-model:value="form.projectName"
|
||||||
|
@done="chooseProject"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="所在地" name="address">
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
placeholder="请输入项目地址"
|
||||||
|
v-model:value="form.address"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</ele-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { message } from 'ant-design-vue/es';
|
||||||
|
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
|
import useFormData from '@/utils/use-form-data';
|
||||||
|
import type { Security } from '@/api/tower/security/model';
|
||||||
|
import { addSecurity, updateSecurity } from '@/api/tower/security';
|
||||||
|
import { Project } from '@/api/tower/project/model';
|
||||||
|
|
||||||
|
// 是否开启响应式布局
|
||||||
|
const themeStore = useThemeStore();
|
||||||
|
const { styleResponsive } = storeToRefs(themeStore);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'done'): void;
|
||||||
|
(e: 'update:visible', visible: boolean): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
// 弹窗是否打开
|
||||||
|
visible: boolean;
|
||||||
|
// 修改回显的数据
|
||||||
|
data?: Security | null;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance | null>(null);
|
||||||
|
// 是否是修改
|
||||||
|
const isUpdate = ref(false);
|
||||||
|
// 提交状态
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const { form, resetFields, assignFields } = useFormData<Security>({
|
||||||
|
securityId: undefined,
|
||||||
|
projectId: undefined,
|
||||||
|
projectName: undefined,
|
||||||
|
securityCode: undefined,
|
||||||
|
address: '',
|
||||||
|
status: 0,
|
||||||
|
sortNumber: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = reactive<Record<string, Rule[]>>({
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备名称',
|
||||||
|
type: 'string',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
model: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备型号',
|
||||||
|
type: 'string',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yearLife: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备使用年限',
|
||||||
|
type: 'number',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
sortNumber: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入排序号',
|
||||||
|
type: 'number',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 保存编辑 */
|
||||||
|
const save = () => {
|
||||||
|
if (!formRef.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(() => {
|
||||||
|
loading.value = true;
|
||||||
|
const categoryForm = {
|
||||||
|
...form
|
||||||
|
};
|
||||||
|
const saveOrUpdate = isUpdate.value ? updateSecurity : addSecurity;
|
||||||
|
saveOrUpdate(categoryForm)
|
||||||
|
.then((msg) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.success(msg);
|
||||||
|
updateVisible(false);
|
||||||
|
emit('done');
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 更新visible */
|
||||||
|
const updateVisible = (value: boolean) => {
|
||||||
|
emit('update:visible', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const chooseProject = (row: Project) => {
|
||||||
|
console.log(row);
|
||||||
|
form.projectId = row.projectId;
|
||||||
|
form.projectName = row.projectName;
|
||||||
|
form.address = row.projectAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible) {
|
||||||
|
if (props.data) {
|
||||||
|
assignFields({
|
||||||
|
...props.data
|
||||||
|
});
|
||||||
|
isUpdate.value = true;
|
||||||
|
} else {
|
||||||
|
isUpdate.value = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resetFields();
|
||||||
|
formRef.value?.clearValidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.tab-pane {
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
.ml-10 {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
222
src/views/tower/maintenance/security-record/index.vue
Normal file
222
src/views/tower/maintenance/security-record/index.vue
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ele-body">
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<!-- 表格 -->
|
||||||
|
<ele-pro-table
|
||||||
|
ref="tableRef"
|
||||||
|
row-key="securityRecordId"
|
||||||
|
:columns="columns"
|
||||||
|
:datasource="datasource"
|
||||||
|
:customRow="customRow"
|
||||||
|
:expand-icon-column-index="1"
|
||||||
|
:scroll="{ x: 1200 }"
|
||||||
|
cache-key="towerModel"
|
||||||
|
>
|
||||||
|
<template #toolbar>
|
||||||
|
<a-space>
|
||||||
|
<ProjectSelectModel
|
||||||
|
:placeholder="`请选择项目`"
|
||||||
|
v-model:value="projectName"
|
||||||
|
@done="chooseProject"
|
||||||
|
/>
|
||||||
|
<a-radio-group v-model:value="searchStatus" @change="onStatus">
|
||||||
|
<a-radio-button value="0">正常</a-radio-button>
|
||||||
|
<a-radio-button value="1">待修</a-radio-button>
|
||||||
|
<a-radio-button value="2">异常已修</a-radio-button>
|
||||||
|
<a-radio-button value="3">异常未修</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
<a-range-picker
|
||||||
|
v-model:value="dateRange"
|
||||||
|
@change="onRange"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
class="ele-fluid"
|
||||||
|
/>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'userId'">
|
||||||
|
{{ `${record.nickname}` }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'images'">
|
||||||
|
<a-image :src="record.images" :width="120" />
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'longitude'">
|
||||||
|
{{ `${record.longitude}, ${record.latitude}` }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'status'">
|
||||||
|
<a-tag v-if="record.status == 0">正常</a-tag>
|
||||||
|
<a-tag v-if="record.status == 1" color="red">待修</a-tag>
|
||||||
|
<a-tag v-if="record.status == 2" color="green">异常已修</a-tag>
|
||||||
|
<a-tag v-if="record.status == 3" color="orange">异常未修</a-tag>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a-space>
|
||||||
|
<a @click="openEdit(record)">修改</a>
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<a-popconfirm
|
||||||
|
placement="topRight"
|
||||||
|
title="确定要删除此记录吗?"
|
||||||
|
@confirm="remove(record)"
|
||||||
|
>
|
||||||
|
<a class="ele-text-danger">删除</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</ele-pro-table>
|
||||||
|
</a-card>
|
||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<SecurityRecordEdit
|
||||||
|
v-model:visible="showEdit"
|
||||||
|
:data="current"
|
||||||
|
@done="reload"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { message } from 'ant-design-vue/es';
|
||||||
|
import type {
|
||||||
|
DatasourceFunction,
|
||||||
|
ColumnItem
|
||||||
|
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
|
import { messageLoading, toDateString } from 'ele-admin-pro/es';
|
||||||
|
import type { EleProTable } from 'ele-admin-pro/es';
|
||||||
|
import type {
|
||||||
|
SecurityRecord,
|
||||||
|
SecurityRecordParam
|
||||||
|
} from '@/api/tower/security-record/model';
|
||||||
|
import {
|
||||||
|
pageSecurityRecord,
|
||||||
|
removeSecurityRecord
|
||||||
|
} from '@/api/tower/security-record';
|
||||||
|
import SecurityRecordEdit from './components/security-record-edit.vue';
|
||||||
|
import { Project } from '@/api/tower/project/model';
|
||||||
|
|
||||||
|
// 表格实例
|
||||||
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const columns = ref<ColumnItem[]>([
|
||||||
|
{
|
||||||
|
title: '操作人',
|
||||||
|
dataIndex: 'userId',
|
||||||
|
key: 'userId'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '现场图片',
|
||||||
|
dataIndex: 'images',
|
||||||
|
key: 'images'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '定位',
|
||||||
|
dataIndex: 'longitude',
|
||||||
|
key: 'longitude'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注说明',
|
||||||
|
dataIndex: 'comments',
|
||||||
|
key: 'comments'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '完成状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
key: 'status',
|
||||||
|
width: 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
width: 180,
|
||||||
|
customRender: ({ text }) => toDateString(text)
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 当前编辑数据
|
||||||
|
const current = ref<SecurityRecord | null>(null);
|
||||||
|
const searchText = ref('');
|
||||||
|
const searchStatus = ref('');
|
||||||
|
// 是否显示编辑弹窗
|
||||||
|
const showEdit = ref(false);
|
||||||
|
const projectName = ref('');
|
||||||
|
|
||||||
|
// 日期范围选择
|
||||||
|
const dateRange = ref<[string, string]>(['', '']);
|
||||||
|
/* 搜索 */
|
||||||
|
const onRange = () => {
|
||||||
|
const [d1, d2] = dateRange.value ?? [];
|
||||||
|
reload({
|
||||||
|
createTimeStart: d1 ? d1 + ' 00:00:00' : '',
|
||||||
|
createTimeEnd: d2 ? d2 + ' 23:59:59' : ''
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表格数据源
|
||||||
|
const datasource: DatasourceFunction = ({ where }) => {
|
||||||
|
if (searchText.value && searchText.value != '') {
|
||||||
|
where.keywords = searchText.value;
|
||||||
|
}
|
||||||
|
return pageSecurityRecord({ ...where });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 刷新表格 */
|
||||||
|
const reload = (where?: SecurityRecordParam) => {
|
||||||
|
tableRef?.value?.reload({ where });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 打开编辑弹窗 */
|
||||||
|
const openEdit = (row?: SecurityRecord | null, id?: number) => {
|
||||||
|
current.value = row ?? null;
|
||||||
|
showEdit.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const search = (searchText) => {
|
||||||
|
reload({ keywords: searchText });
|
||||||
|
};
|
||||||
|
|
||||||
|
const chooseProject = (row: Project) => {
|
||||||
|
reload({ projectId: row.projectId });
|
||||||
|
};
|
||||||
|
|
||||||
|
const onStatus = (e: any) => {
|
||||||
|
console.log(e.target.value);
|
||||||
|
const status = e.target.value;
|
||||||
|
reload({ status });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 删除单个 */
|
||||||
|
const remove = (row: SecurityRecord) => {
|
||||||
|
const hide = messageLoading('请求中..', 0);
|
||||||
|
removeSecurityRecord(row.securityRecordId)
|
||||||
|
.then((msg) => {
|
||||||
|
hide();
|
||||||
|
message.success(msg);
|
||||||
|
reload();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
hide();
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 自定义行属性 */
|
||||||
|
const customRow = (record: SecurityRecord) => {
|
||||||
|
return {
|
||||||
|
// 行点击事件
|
||||||
|
onClick: () => {
|
||||||
|
// console.log(record);
|
||||||
|
},
|
||||||
|
// 行双击事件
|
||||||
|
onDblclick: () => {
|
||||||
|
openEdit(record);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'TowerSecurityRecord'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<template>
|
||||||
|
<ele-modal
|
||||||
|
:width="740"
|
||||||
|
:visible="visible"
|
||||||
|
:confirm-loading="loading"
|
||||||
|
:title="isUpdate ? '修改分类' : '新建分类'"
|
||||||
|
:body-style="{ paddingBottom: '8px' }"
|
||||||
|
@update:visible="updateVisible"
|
||||||
|
@ok="save"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="styleResponsive ? { md: 6, sm: 4, xs: 24 } : { flex: '90px' }"
|
||||||
|
:wrapper-col="
|
||||||
|
styleResponsive ? { md: 18, sm: 20, xs: 24 } : { flex: '1' }
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col
|
||||||
|
v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 12 }"
|
||||||
|
>
|
||||||
|
<a-form-item label="上级分类" name="parentId">
|
||||||
|
<a-tree-select
|
||||||
|
allow-clear
|
||||||
|
:tree-data="categoryList"
|
||||||
|
tree-default-expand-all
|
||||||
|
placeholder="请选择上级分类"
|
||||||
|
:value="form.parentId || undefined"
|
||||||
|
:dropdown-style="{ maxHeight: '360px', overflow: 'auto' }"
|
||||||
|
@update:value="(value?: number) => (form.parentId = value)"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="设备型号" name="title">
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
placeholder="请输入分类名称"
|
||||||
|
v-model:value="form.title"
|
||||||
|
@pressEnter="save"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="使用年限" name="yearLife">
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
placeholder="请输入分类名称"
|
||||||
|
v-model:value="form.yearLife"
|
||||||
|
@pressEnter="save"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</ele-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { message } from 'ant-design-vue/es';
|
||||||
|
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
|
import useFormData from '@/utils/use-form-data';
|
||||||
|
import type { Security } from '@/api/tower/security/model';
|
||||||
|
import { addSecurity, updateSecurity } from '@/api/tower/security';
|
||||||
|
import { FILE_SERVER } from "@/config/setting";
|
||||||
|
import { ItemType } from "ele-admin-pro/es/ele-image-upload/types";
|
||||||
|
import { uploadFile } from "@/api/system/file";
|
||||||
|
import { LoginRecordParam } from "@/api/system/login-record/model";
|
||||||
|
|
||||||
|
// 是否开启响应式布局
|
||||||
|
const themeStore = useThemeStore();
|
||||||
|
const { styleResponsive } = storeToRefs(themeStore);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'done'): void;
|
||||||
|
(e: 'update:visible', visible: boolean): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
// 弹窗是否打开
|
||||||
|
visible: boolean;
|
||||||
|
// 修改回显的数据
|
||||||
|
data?: Security | null;
|
||||||
|
// 上级分类id
|
||||||
|
parentId?: number;
|
||||||
|
// 全部分类数据
|
||||||
|
categoryList: Security[];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const { form, resetFields, assignFields } = useFormData<Security>({
|
||||||
|
securityId: undefined,
|
||||||
|
projectName: undefined,
|
||||||
|
securityCode: undefined,
|
||||||
|
regionName: '',
|
||||||
|
status: 0,
|
||||||
|
address: undefined,
|
||||||
|
sortNumber: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
const formRef = ref<FormInstance | null>(null);
|
||||||
|
// 是否是修改
|
||||||
|
const isUpdate = ref(false);
|
||||||
|
// 提交状态
|
||||||
|
const loading = ref(false);
|
||||||
|
// 已上传数据, 可赋初始值用于回显
|
||||||
|
const images = ref([]);
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = reactive<Record<string, Rule[]>>({
|
||||||
|
title: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入分类名称',
|
||||||
|
type: 'string',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
sortNumber: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入排序号',
|
||||||
|
type: 'number',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
meta: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
validator: async (_rule: Rule, value: string) => {
|
||||||
|
if (value) {
|
||||||
|
const msg = '请输入正确的JSON格式';
|
||||||
|
try {
|
||||||
|
const obj = JSON.parse(value);
|
||||||
|
if (typeof obj !== 'object' || obj === null) {
|
||||||
|
return Promise.reject(msg);
|
||||||
|
}
|
||||||
|
} catch (_e) {
|
||||||
|
return Promise.reject(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
const onUpload = (d: ItemType) => {
|
||||||
|
uploadFile(<File>d.file)
|
||||||
|
.then((result) => {
|
||||||
|
form.image = result.path;
|
||||||
|
message.success('上传成功');
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
form.image = ''
|
||||||
|
}
|
||||||
|
/* 保存编辑 */
|
||||||
|
const save = () => {
|
||||||
|
if (!formRef.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(() => {
|
||||||
|
loading.value = true;
|
||||||
|
const categoryForm = {
|
||||||
|
...form,
|
||||||
|
parentId: form.parentId || 0
|
||||||
|
};
|
||||||
|
const saveOrUpdate = isUpdate.value ? updateSecurity : addSecurity;
|
||||||
|
saveOrUpdate(categoryForm)
|
||||||
|
.then((msg) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.success(msg);
|
||||||
|
updateVisible(false);
|
||||||
|
emit('done');
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 更新visible */
|
||||||
|
const updateVisible = (value: boolean) => {
|
||||||
|
emit('update:visible', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateHideValue = (value: boolean) => {
|
||||||
|
form.status = value ? 0 : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible) {
|
||||||
|
if (props.data) {
|
||||||
|
// 头像赋值
|
||||||
|
images.value = [];
|
||||||
|
if(props.data.image){
|
||||||
|
images.value.push({ uid:1, url: props.data.image, status: '' });
|
||||||
|
}
|
||||||
|
assignFields({
|
||||||
|
...props.data,
|
||||||
|
parentId:
|
||||||
|
props.data.parentId === 0 ? undefined : props.data.parentId
|
||||||
|
});
|
||||||
|
isUpdate.value = true;
|
||||||
|
} else {
|
||||||
|
form.parentId = props.parentId;
|
||||||
|
isUpdate.value = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resetFields();
|
||||||
|
formRef.value?.clearValidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import * as icons from '@/layout/menu-icons';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: icons,
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
iconData: [
|
||||||
|
{
|
||||||
|
title: '已引入的图标',
|
||||||
|
icons: Object.keys(icons)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<template xmlns="">
|
||||||
|
<ele-modal
|
||||||
|
:width="500"
|
||||||
|
:visible="visible"
|
||||||
|
:confirm-loading="loading"
|
||||||
|
:title="isUpdate ? '修改保养计划' : '新建保养计划'"
|
||||||
|
:body-style="{ paddingBottom: '8px' }"
|
||||||
|
@update:visible="updateVisible"
|
||||||
|
@ok="save"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="styleResponsive ? { md: 6, sm: 6, xs: 24 } : { flex: '90px' }"
|
||||||
|
:wrapper-col="
|
||||||
|
styleResponsive ? { md: 18, sm: 20, xs: 24 } : { flex: '1' }
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col
|
||||||
|
v-bind="styleResponsive ? { md: 22, sm: 24, xs: 24 } : { span: 12 }"
|
||||||
|
>
|
||||||
|
<a-form-item label="项目名称" name="name">
|
||||||
|
<ProjectSelectModel
|
||||||
|
:placeholder="`请选择项目`"
|
||||||
|
v-model:value="form.projectName"
|
||||||
|
@done="chooseProject"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="所在地" name="address">
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
placeholder="请输入项目地址"
|
||||||
|
v-model:value="form.address"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</ele-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { message } from 'ant-design-vue/es';
|
||||||
|
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
|
import useFormData from '@/utils/use-form-data';
|
||||||
|
import type { Security } from '@/api/tower/security/model';
|
||||||
|
import { addSecurity, updateSecurity } from '@/api/tower/security';
|
||||||
|
import { Project } from '@/api/tower/project/model';
|
||||||
|
|
||||||
|
// 是否开启响应式布局
|
||||||
|
const themeStore = useThemeStore();
|
||||||
|
const { styleResponsive } = storeToRefs(themeStore);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'done'): void;
|
||||||
|
(e: 'update:visible', visible: boolean): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
// 弹窗是否打开
|
||||||
|
visible: boolean;
|
||||||
|
// 修改回显的数据
|
||||||
|
data?: Security | null;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance | null>(null);
|
||||||
|
// 是否是修改
|
||||||
|
const isUpdate = ref(false);
|
||||||
|
// 提交状态
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const { form, resetFields, assignFields } = useFormData<Security>({
|
||||||
|
securityId: undefined,
|
||||||
|
projectId: undefined,
|
||||||
|
projectName: undefined,
|
||||||
|
securityCode: undefined,
|
||||||
|
address: '',
|
||||||
|
status: 0,
|
||||||
|
sortNumber: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = reactive<Record<string, Rule[]>>({
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备名称',
|
||||||
|
type: 'string',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
model: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备型号',
|
||||||
|
type: 'string',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yearLife: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备使用年限',
|
||||||
|
type: 'number',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
sortNumber: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入排序号',
|
||||||
|
type: 'number',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 保存编辑 */
|
||||||
|
const save = () => {
|
||||||
|
if (!formRef.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(() => {
|
||||||
|
loading.value = true;
|
||||||
|
const categoryForm = {
|
||||||
|
...form
|
||||||
|
};
|
||||||
|
const saveOrUpdate = isUpdate.value ? updateSecurity : addSecurity;
|
||||||
|
saveOrUpdate(categoryForm)
|
||||||
|
.then((msg) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.success(msg);
|
||||||
|
updateVisible(false);
|
||||||
|
emit('done');
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 更新visible */
|
||||||
|
const updateVisible = (value: boolean) => {
|
||||||
|
emit('update:visible', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const chooseProject = (row: Project) => {
|
||||||
|
console.log(row);
|
||||||
|
form.projectId = row.projectId;
|
||||||
|
form.projectName = row.projectName;
|
||||||
|
form.address = row.projectAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible) {
|
||||||
|
if (props.data) {
|
||||||
|
assignFields({
|
||||||
|
...props.data
|
||||||
|
});
|
||||||
|
isUpdate.value = true;
|
||||||
|
} else {
|
||||||
|
isUpdate.value = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resetFields();
|
||||||
|
formRef.value?.clearValidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.tab-pane {
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
.ml-10 {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<template>
|
||||||
|
<ele-modal
|
||||||
|
:width="1000"
|
||||||
|
:visible="visible"
|
||||||
|
:confirm-loading="loading"
|
||||||
|
:title="isUpdate ? '保养记录' : '保养记录'"
|
||||||
|
:body-style="{ paddingBottom: '8px' }"
|
||||||
|
@update:visible="updateVisible"
|
||||||
|
@ok="save"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="styleResponsive ? { md: 6, sm: 6, xs: 24 } : { flex: '90px' }"
|
||||||
|
:wrapper-col="
|
||||||
|
styleResponsive ? { md: 18, sm: 20, xs: 24 } : { flex: '1' }
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col
|
||||||
|
v-bind="styleResponsive ? { md: 22, sm: 24, xs: 24 } : { span: 12 }"
|
||||||
|
/>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</ele-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { message } from 'ant-design-vue/es';
|
||||||
|
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
|
import useFormData from '@/utils/use-form-data';
|
||||||
|
import type { TowerModel } from '@/api/tower/model/model';
|
||||||
|
import { addTowerModel, updateTowerModel } from '@/api/tower/model';
|
||||||
|
|
||||||
|
// 是否开启响应式布局
|
||||||
|
const themeStore = useThemeStore();
|
||||||
|
const { styleResponsive } = storeToRefs(themeStore);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'done'): void;
|
||||||
|
(e: 'update:visible', visible: boolean): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
// 弹窗是否打开
|
||||||
|
visible: boolean;
|
||||||
|
// 修改回显的数据
|
||||||
|
data?: TowerModel | null;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance | null>(null);
|
||||||
|
// 是否是修改
|
||||||
|
const isUpdate = ref(false);
|
||||||
|
// 提交状态
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const { form, resetFields, assignFields } = useFormData<TowerModel>({
|
||||||
|
name: '',
|
||||||
|
modelId: undefined,
|
||||||
|
model: undefined,
|
||||||
|
image: '',
|
||||||
|
status: 0,
|
||||||
|
yearLife: undefined,
|
||||||
|
sortNumber: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = reactive<Record<string, Rule[]>>({
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备名称',
|
||||||
|
type: 'string',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
model: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备型号',
|
||||||
|
type: 'string',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yearLife: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备使用年限',
|
||||||
|
type: 'number',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
sortNumber: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入排序号',
|
||||||
|
type: 'number',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 保存编辑 */
|
||||||
|
const save = () => {
|
||||||
|
if (!formRef.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(() => {
|
||||||
|
loading.value = true;
|
||||||
|
const categoryForm = {
|
||||||
|
...form
|
||||||
|
};
|
||||||
|
const saveOrUpdate = isUpdate.value ? updateTowerModel : addTowerModel;
|
||||||
|
saveOrUpdate(categoryForm)
|
||||||
|
.then((msg) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.success(msg);
|
||||||
|
updateVisible(false);
|
||||||
|
emit('done');
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
loading.value = false;
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 更新visible */
|
||||||
|
const updateVisible = (value: boolean) => {
|
||||||
|
emit('update:visible', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible) {
|
||||||
|
if (props.data) {
|
||||||
|
assignFields({
|
||||||
|
...props.data
|
||||||
|
});
|
||||||
|
isUpdate.value = true;
|
||||||
|
} else {
|
||||||
|
isUpdate.value = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resetFields();
|
||||||
|
formRef.value?.clearValidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.tab-pane {
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
.ml-10 {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
242
src/views/tower/maintenance/security/index.vue
Normal file
242
src/views/tower/maintenance/security/index.vue
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ele-body">
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<!-- 表格 -->
|
||||||
|
<ele-pro-table
|
||||||
|
ref="tableRef"
|
||||||
|
row-key="securityId"
|
||||||
|
:columns="columns"
|
||||||
|
:datasource="datasource"
|
||||||
|
:customRow="customRow"
|
||||||
|
:expand-icon-column-index="1"
|
||||||
|
:scroll="{ x: 1200 }"
|
||||||
|
cache-key="towerModel"
|
||||||
|
>
|
||||||
|
<template #toolbar>
|
||||||
|
<a-space>
|
||||||
|
<a-button type="primary" class="ele-btn-icon" @click="openEdit()">
|
||||||
|
<template #icon>
|
||||||
|
<plus-outlined />
|
||||||
|
</template>
|
||||||
|
<span>新建</span>
|
||||||
|
</a-button>
|
||||||
|
<!-- 搜索表单 -->
|
||||||
|
<a-input-search
|
||||||
|
allow-clear
|
||||||
|
v-model:value="searchText"
|
||||||
|
placeholder="请输入搜索关键词"
|
||||||
|
@search="search"
|
||||||
|
@pressEnter="search"
|
||||||
|
/>
|
||||||
|
<a-radio-group v-model:value="searchStatus" @change="onStatus">
|
||||||
|
<a-radio-button value="0">正常</a-radio-button>
|
||||||
|
<a-radio-button value="1">待修</a-radio-button>
|
||||||
|
<a-radio-button value="2">异常已修</a-radio-button>
|
||||||
|
<a-radio-button value="3">异常未修</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
<a-range-picker
|
||||||
|
v-model:value="dateRange"
|
||||||
|
@change="onRange"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
class="ele-fluid"
|
||||||
|
/>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'status'">
|
||||||
|
<a-tag v-if="record.status == 0">正常</a-tag>
|
||||||
|
<a-tag v-if="record.status == 1" color="red">待修</a-tag>
|
||||||
|
<a-tag v-if="record.status == 2" color="green">异常已修</a-tag>
|
||||||
|
<a-tag v-if="record.status == 3" color="orange">异常未修</a-tag>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<a-space>
|
||||||
|
<a @click="openRecord(record)">保养记录</a>
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<a @click="openEdit(record)">修改</a>
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<a-popconfirm
|
||||||
|
placement="topRight"
|
||||||
|
title="确定要删除此记录吗?"
|
||||||
|
@confirm="remove(record)"
|
||||||
|
>
|
||||||
|
<a class="ele-text-danger">删除</a>
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</ele-pro-table>
|
||||||
|
</a-card>
|
||||||
|
<!-- 编辑弹窗 -->
|
||||||
|
<SecurityEdit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||||
|
<!-- 保养记录 -->
|
||||||
|
<SecurityRecord
|
||||||
|
v-model:visible="showRecord"
|
||||||
|
:data="current"
|
||||||
|
@done="reload"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { message } from 'ant-design-vue/es';
|
||||||
|
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||||
|
import type {
|
||||||
|
DatasourceFunction,
|
||||||
|
ColumnItem
|
||||||
|
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||||
|
import { messageLoading, toDateString } from 'ele-admin-pro/es';
|
||||||
|
import type { EleProTable } from 'ele-admin-pro/es';
|
||||||
|
import type { Security, SecurityParam } from '@/api/tower/security/model';
|
||||||
|
import {
|
||||||
|
pageSecurity,
|
||||||
|
listSecurity,
|
||||||
|
removeSecurity
|
||||||
|
} from '@/api/tower/security';
|
||||||
|
import SecurityEdit from './components/security-edit.vue';
|
||||||
|
import SecurityRecord from './components/security-record.vue';
|
||||||
|
|
||||||
|
// 表格实例
|
||||||
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const columns = ref<ColumnItem[]>([
|
||||||
|
// {
|
||||||
|
// key: 'index',
|
||||||
|
// width: 48,
|
||||||
|
// align: 'center',
|
||||||
|
// fixed: 'left',
|
||||||
|
// hideInSetting: true,
|
||||||
|
// customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: 'ID',
|
||||||
|
// dataIndex: 'securityId',
|
||||||
|
// key: 'securityId'
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
title: '保养编号',
|
||||||
|
dataIndex: 'securityCode',
|
||||||
|
key: 'securityCode'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '项目名称',
|
||||||
|
dataIndex: 'projectName',
|
||||||
|
key: 'projectName'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '所在地',
|
||||||
|
dataIndex: 'address',
|
||||||
|
key: 'address',
|
||||||
|
showSorterTooltip: false,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
key: 'status',
|
||||||
|
width: 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '生成时间',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
width: 180,
|
||||||
|
customRender: ({ text }) => toDateString(text)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: 200,
|
||||||
|
align: 'center'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 当前编辑数据
|
||||||
|
const current = ref<Security | null>(null);
|
||||||
|
const searchText = ref('');
|
||||||
|
const searchStatus = ref('');
|
||||||
|
// 是否显示编辑弹窗
|
||||||
|
const showEdit = ref(false);
|
||||||
|
const showRecord = ref(false);
|
||||||
|
|
||||||
|
// 日期范围选择
|
||||||
|
const dateRange = ref<[string, string]>(['', '']);
|
||||||
|
/* 搜索 */
|
||||||
|
const onRange = () => {
|
||||||
|
const [d1, d2] = dateRange.value ?? [];
|
||||||
|
reload({
|
||||||
|
createTimeStart: d1 ? d1 + ' 00:00:00' : '',
|
||||||
|
createTimeEnd: d2 ? d2 + ' 23:59:59' : ''
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表格数据源
|
||||||
|
const datasource: DatasourceFunction = ({ where }) => {
|
||||||
|
if (searchText.value && searchText.value != '') {
|
||||||
|
where.keywords = searchText.value;
|
||||||
|
}
|
||||||
|
return pageSecurity({ ...where });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 刷新表格 */
|
||||||
|
const reload = (where?: SecurityParam) => {
|
||||||
|
tableRef?.value?.reload({ where });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 打开编辑弹窗 */
|
||||||
|
const openEdit = (row?: Security | null, id?: number) => {
|
||||||
|
current.value = row ?? null;
|
||||||
|
showEdit.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const openRecord = (row?: Security, id?: number) => {
|
||||||
|
current.value = row ?? null;
|
||||||
|
showRecord.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const search = (searchText) => {
|
||||||
|
reload({ keywords: searchText });
|
||||||
|
};
|
||||||
|
|
||||||
|
const onStatus = (e: any) => {
|
||||||
|
console.log(e.target.value);
|
||||||
|
const status = e.target.value;
|
||||||
|
reload({ status });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 删除单个 */
|
||||||
|
const remove = (row: Security) => {
|
||||||
|
const hide = messageLoading('请求中..', 0);
|
||||||
|
removeSecurity(row.securityId)
|
||||||
|
.then((msg) => {
|
||||||
|
hide();
|
||||||
|
message.success(msg);
|
||||||
|
reload();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
hide();
|
||||||
|
message.error(e.message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 自定义行属性 */
|
||||||
|
const customRow = (record: Security) => {
|
||||||
|
return {
|
||||||
|
// 行点击事件
|
||||||
|
onClick: () => {
|
||||||
|
// console.log(record);
|
||||||
|
},
|
||||||
|
// 行双击事件
|
||||||
|
onDblclick: () => {
|
||||||
|
openEdit(record);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'TowerSecurity'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user