新增:每月1日自动生成保养计划
This commit is contained in:
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,30 +54,26 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="其他说明备注">
|
||||
<a-input
|
||||
allow-clear
|
||||
v-model:value="form.remark"
|
||||
/>
|
||||
<a-input allow-clear v-model:value="form.remark" />
|
||||
</a-form-item>
|
||||
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="出租单位" v-bind="validateInfos.companyId">
|
||||
{{ companyName }}
|
||||
<!-- <SelectCompany-->
|
||||
<!-- :placeholder="`请选择出租单位`"-->
|
||||
<!-- v-model:value="companyName"-->
|
||||
<!-- @done="chooseCompany"-->
|
||||
<!-- />-->
|
||||
<!-- <SelectCompany-->
|
||||
<!-- :placeholder="`请选择出租单位`"-->
|
||||
<!-- v-model:value="companyName"-->
|
||||
<!-- @done="chooseCompany"-->
|
||||
<!-- />-->
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="承租单位" v-bind="validateInfos.customerId">
|
||||
{{ customerName }}
|
||||
<!-- <SelectCustomer-->
|
||||
<!-- :placeholder="`请选择承租单位`"-->
|
||||
<!-- v-model:value="customerName"-->
|
||||
<!-- @done="chooseCustomer"-->
|
||||
<!-- />-->
|
||||
<!-- <SelectCustomer-->
|
||||
<!-- :placeholder="`请选择承租单位`"-->
|
||||
<!-- v-model:value="customerName"-->
|
||||
<!-- @done="chooseCustomer"-->
|
||||
<!-- />-->
|
||||
</a-form-item>
|
||||
<a-form-item label="截止日期">
|
||||
<a-date-picker
|
||||
@@ -88,8 +84,14 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="合同存档">
|
||||
<a-switch :checked="form.isInStock" :checked-value="1" :un-checked-value="0" checked-children="已归档"
|
||||
un-checked-children="未归档" @change="changeInStock" />
|
||||
<a-switch
|
||||
:checked="form.isInStock"
|
||||
:checked-value="1"
|
||||
:un-checked-value="0"
|
||||
checked-children="已归档"
|
||||
un-checked-children="未归档"
|
||||
@change="changeInStock"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
@@ -120,10 +122,16 @@
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="是否自动结算">
|
||||
<a-switch :checked="form.autoSettle" :checked-value="1" :un-checked-value="0" checked-children="是"
|
||||
un-checked-children="否" @change="changeAutoSettle" />
|
||||
</a-form-item>
|
||||
<a-form-item label="是否自动结算">
|
||||
<a-switch
|
||||
:checked="form.autoSettle"
|
||||
:checked-value="1"
|
||||
:un-checked-value="0"
|
||||
checked-children="是"
|
||||
un-checked-children="否"
|
||||
@change="changeAutoSettle"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
@@ -139,13 +147,21 @@
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<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-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class="flex flex-col justify-start justify-start"
|
||||
style="padding: 1rem 0;border-top: 1px solid #dcdfe6; border-bottom: 1px solid #dcdfe6">
|
||||
<div
|
||||
class="flex flex-col justify-start justify-start"
|
||||
style="
|
||||
padding: 1rem 0;
|
||||
border-top: 1px solid #dcdfe6;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
"
|
||||
>
|
||||
<div>
|
||||
<p>合同电子存档</p>
|
||||
<div class="flex justify-start">
|
||||
@@ -164,8 +180,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-start items-center"
|
||||
style="padding: 1rem 0;border-top: 1px solid #dcdfe6;">
|
||||
<div
|
||||
class="flex justify-start items-center"
|
||||
style="padding: 1rem 0; border-top: 1px solid #dcdfe6"
|
||||
>
|
||||
<div class="flex justify-start items-center">
|
||||
<unordered-list-outlined />
|
||||
<span>合同签订设备清单</span>
|
||||
@@ -211,62 +229,119 @@
|
||||
</a-col>
|
||||
</a-row>
|
||||
<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>
|
||||
</div>
|
||||
<template v-else>
|
||||
<a-row class="text-center" v-for="(item, index) in contractEquipmentList"
|
||||
:key="index">
|
||||
<a-row
|
||||
class="text-center"
|
||||
v-for="(item, index) in contractEquipmentList"
|
||||
:key="index"
|
||||
>
|
||||
<a-col :span="3" class="p-05 border-r-white">
|
||||
<a-select placeholder="必选项" 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">
|
||||
<a-select
|
||||
placeholder="必选项"
|
||||
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 }})
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
<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 :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 :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>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<a-input v-model:value="contractEquipmentList[index].planRentMonth" size="small" placeholder="必填项"
|
||||
type="number" />
|
||||
<a-input
|
||||
v-model:value="contractEquipmentList[index].planRentMonth"
|
||||
size="small"
|
||||
placeholder="必填项"
|
||||
type="number"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<a-input v-model:value="contractEquipmentList[index].rentAmount" size="small" placeholder="必填项"
|
||||
type="number" />
|
||||
<a-input
|
||||
v-model:value="contractEquipmentList[index].rentAmount"
|
||||
size="small"
|
||||
placeholder="必填项"
|
||||
type="number"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<a-input v-model:value="contractEquipmentList[index].inOutAmount" size="small" placeholder="必填项"
|
||||
type="number" />
|
||||
<a-input
|
||||
v-model:value="contractEquipmentList[index].inOutAmount"
|
||||
size="small"
|
||||
placeholder="必填项"
|
||||
type="number"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<a-input v-model:value="contractEquipmentList[index].workerAmount" size="small" placeholder="必填项"
|
||||
type="number" />
|
||||
<a-input
|
||||
v-model:value="contractEquipmentList[index].workerAmount"
|
||||
size="small"
|
||||
placeholder="必填项"
|
||||
type="number"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<a-input v-model:value="contractEquipmentList[index].otherAmount" size="small" placeholder="必填项"
|
||||
type="number" />
|
||||
<a-input
|
||||
v-model:value="contractEquipmentList[index].otherAmount"
|
||||
size="small"
|
||||
placeholder="必填项"
|
||||
type="number"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<a-input v-model:value="contractEquipmentList[index].preBuryAmount" size="small"
|
||||
type="number" />
|
||||
<a-input
|
||||
v-model:value="contractEquipmentList[index].preBuryAmount"
|
||||
size="small"
|
||||
type="number"
|
||||
/>
|
||||
</a-col>
|
||||
<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 :span="1" class="p-05">
|
||||
<div class="flex justify-center items-center">
|
||||
<close-circle-outlined style="font-size: 1.5rem; color: pink;cursor: pointer"
|
||||
@click.native="delEquipment(index)" />
|
||||
<close-circle-outlined
|
||||
style="font-size: 1.5rem; color: pink; cursor: pointer"
|
||||
@click.native="delEquipment(index)"
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
@@ -285,362 +360,377 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, computed } from "vue";
|
||||
import { Form, message, UploadFile } from "ant-design-vue";
|
||||
import { assignObject } from "ele-admin-pro";
|
||||
import { updateContract, addContract } from "@/api/tower/contract";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { Contract } from "@/api/tower/contract/model";
|
||||
import dayjs from "dayjs";
|
||||
import { ContractFile } from "@/api/tower/contractFile/model";
|
||||
import { ref, reactive, watch, computed } from 'vue';
|
||||
import { Form, message, UploadFile } from 'ant-design-vue';
|
||||
import { assignObject } from 'ele-admin-pro';
|
||||
import { updateContract, addContract } from '@/api/tower/contract';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { Contract } from '@/api/tower/contract/model';
|
||||
import dayjs from 'dayjs';
|
||||
import { ContractFile } from '@/api/tower/contractFile/model';
|
||||
|
||||
import {
|
||||
PlusOutlined,
|
||||
UnorderedListOutlined,
|
||||
CloseCircleOutlined, UploadOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import { ContractEquipment } from "@/api/tower/contractEquipment/model";
|
||||
import { TowerModel } from "@/api/tower/model/model";
|
||||
import { listTowerModel } from "@/api/tower/model";
|
||||
import { addBatchContractFile, listContractFile } from "@/api/tower/contractFile";
|
||||
import { addBatchContractEquipment, listContractEquipment } 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";
|
||||
import {
|
||||
PlusOutlined,
|
||||
UnorderedListOutlined,
|
||||
CloseCircleOutlined,
|
||||
UploadOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { ContractEquipment } from '@/api/tower/contractEquipment/model';
|
||||
import { TowerModel } from '@/api/tower/model/model';
|
||||
import { listTowerModel } from '@/api/tower/model';
|
||||
import {
|
||||
addBatchContractFile,
|
||||
listContractFile
|
||||
} from '@/api/tower/contractFile';
|
||||
import {
|
||||
addBatchContractEquipment,
|
||||
listContractEquipment
|
||||
} 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 loginUser = computed(() => userStore.info ?? {});
|
||||
const token = localStorage.getItem(TOKEN_STORE_NAME);
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
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 useForm = Form.useForm;
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Contract | null;
|
||||
}>();
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
const useForm = Form.useForm;
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Contract | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'done'): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
// 是否显示最大化切换按钮
|
||||
const maxable = ref(true);
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
// 是否显示最大化切换按钮
|
||||
const maxable = ref(true);
|
||||
|
||||
// 用户信息
|
||||
const form = reactive<Contract>({
|
||||
contractId: undefined,
|
||||
projectId: undefined,
|
||||
companyId: undefined,
|
||||
customerId: undefined,
|
||||
customerContact: "",
|
||||
contactNumber: "",
|
||||
signDate: "",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
contractAmount: undefined,
|
||||
contactAgreeAmount: undefined,
|
||||
totalSettleAmount: 0,
|
||||
totalIncomeAmount: 0,
|
||||
isInStock: 0,
|
||||
autoSettle: 0,
|
||||
payRate: undefined,
|
||||
remark: "",
|
||||
fileList: "[]"
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
projectId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择项目",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
// contactNumber: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: "请输入合同编号",
|
||||
// trigger: "blur"
|
||||
// }
|
||||
// ],
|
||||
companyId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择出租单位",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
customerId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择承租单位",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const projectName = ref<string>("");
|
||||
const chooseProject = (res) => {
|
||||
// console.log(res)
|
||||
projectName.value = res.projectName;
|
||||
form.projectId = res.projectId;
|
||||
|
||||
companyName.value = res.companyName;
|
||||
form.companyId = res.companyId;
|
||||
|
||||
customerName.value = res.customerName;
|
||||
form.customerId = res.customerId;
|
||||
};
|
||||
|
||||
const companyName = ref<string>();
|
||||
const chooseCompany = (res: Company) => {
|
||||
companyName.value = res.companyName;
|
||||
form.companyId = res.companyId;
|
||||
};
|
||||
|
||||
const customerName = ref<string>("");
|
||||
const chooseCustomer = (res: Customer) => {
|
||||
customerName.value = res.name;
|
||||
form.customerId = res.customerId;
|
||||
form.customerContact = res.contact;
|
||||
};
|
||||
|
||||
const changeInStock = (checked) => {
|
||||
form.isInStock = checked;
|
||||
};
|
||||
|
||||
const changeAutoSettle = (checked) => {
|
||||
form.autoSettle = checked;
|
||||
};
|
||||
|
||||
|
||||
const fileList = ref<FileItem[]>([]);
|
||||
|
||||
interface FileInfo {
|
||||
file: FileItem;
|
||||
fileList: FileItem[];
|
||||
}
|
||||
|
||||
const onFileUpload = (info: FileInfo) => {
|
||||
let resFileList = [...info.fileList];
|
||||
fileList.value = resFileList.map((file) => {
|
||||
if (file.response) {
|
||||
// Component will show file.url as link
|
||||
file.url = file.response.url;
|
||||
}
|
||||
return file;
|
||||
// 用户信息
|
||||
const form = reactive<Contract>({
|
||||
contractId: undefined,
|
||||
projectId: undefined,
|
||||
companyId: undefined,
|
||||
customerId: undefined,
|
||||
customerContact: '',
|
||||
contactNumber: '',
|
||||
signDate: '',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
contractAmount: undefined,
|
||||
contactAgreeAmount: undefined,
|
||||
totalSettleAmount: 0,
|
||||
totalIncomeAmount: 0,
|
||||
isInStock: 0,
|
||||
autoSettle: 0,
|
||||
payRate: undefined,
|
||||
remark: '',
|
||||
fileList: '[]'
|
||||
});
|
||||
form.fileList = JSON.stringify(fileList.value);
|
||||
};
|
||||
|
||||
const contractFileList = ref<ContractFile[]>([]);
|
||||
const uploadFile = path => {
|
||||
contractFileList.value.push({ path, contractId: 0, userId: loginUser.value.userId });
|
||||
};
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
|
||||
const delFile = index => {
|
||||
contractFileList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const getContractFileList = async () => {
|
||||
contractFileList.value = await listContractFile({ contractId: props.data?.contractId });
|
||||
};
|
||||
|
||||
const equipmentList = ref<TowerEquipment[]>([]);
|
||||
const getEquipmentList = async () => {
|
||||
equipmentList.value = await listTowerEquipment();
|
||||
};
|
||||
|
||||
const equipmentModelList = ref<TowerModel[]>([]);
|
||||
const getEquipmentModelList = async () => {
|
||||
equipmentModelList.value = await listTowerModel();
|
||||
};
|
||||
|
||||
const contractEquipmentList = ref<ContractEquipment[]>([]);
|
||||
const getContractEquipmentList = async () => {
|
||||
contractEquipmentList.value = await listContractEquipment({ contractId: props.data?.contractId });
|
||||
};
|
||||
|
||||
const chooseEquipmentName = (res, index) => {
|
||||
contractEquipmentList.value[index].equipmentName = res.name;
|
||||
};
|
||||
|
||||
const delEquipment = index => {
|
||||
contractEquipmentList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const addEquipment = () => {
|
||||
contractEquipmentList.value.push({
|
||||
contractEquipmentId: null,
|
||||
contractId: null,
|
||||
equipmentId: undefined,
|
||||
equipmentName: "",
|
||||
equipmentModel: "",
|
||||
num: null,
|
||||
planRentMonth: null,
|
||||
rentAmount: null,
|
||||
inOutAmount: null,
|
||||
workerAmount: null,
|
||||
otherAmount: null,
|
||||
preBuryAmount: null,
|
||||
remark: null
|
||||
});
|
||||
};
|
||||
|
||||
const { resetFields, validate, validateInfos } = useForm(form, rules);
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
validate()
|
||||
.then(async () => {
|
||||
loading.value = true;
|
||||
// 去除空格
|
||||
form.contactNumber = form.contactNumber?.replace(/\s*/g, "");
|
||||
// 判断权限
|
||||
// if (loginUser.value.roles?.[0].roleCode != 'admin'){
|
||||
// form.status = '1';
|
||||
// }
|
||||
const data = {
|
||||
...form
|
||||
};
|
||||
for (let i = 0; i < contractEquipmentList.value.length; i++) {
|
||||
if (!contractEquipmentList.value[i].equipmentId) {
|
||||
loading.value = false;
|
||||
message.error("请选择设备");
|
||||
return;
|
||||
}
|
||||
if (!contractEquipmentList.value[i].equipmentModel) {
|
||||
loading.value = false;
|
||||
message.error("请选择设备型号");
|
||||
return;
|
||||
}
|
||||
if (!contractEquipmentList.value[i].num) {
|
||||
loading.value = false;
|
||||
message.error("请输入签订数量");
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].planRentMonth === null) {
|
||||
loading.value = false;
|
||||
message.error("请输入计划租期");
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].rentAmount === null) {
|
||||
loading.value = false;
|
||||
message.error("请输入租金");
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].inOutAmount === null) {
|
||||
loading.value = false;
|
||||
message.error("请输入进退场费");
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].workerAmount === null) {
|
||||
loading.value = false;
|
||||
message.error("请输入劳务费用");
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].otherAmount === null) {
|
||||
loading.value = false;
|
||||
message.error("请输入其他费用");
|
||||
return;
|
||||
}
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
projectId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择项目',
|
||||
trigger: 'blur'
|
||||
}
|
||||
// 转字符串
|
||||
const saveOrUpdate = isUpdate.value ? updateContract : addContract;
|
||||
const res = await saveOrUpdate(data).catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
const contractId = res?.data;
|
||||
// if (contractFileList.value.length > 0) await saveFileList(contractId);
|
||||
if (contractEquipmentList.value.length > 0) await saveEquipmentList(contractId);
|
||||
loading.value = false;
|
||||
message.success(res?.message);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
],
|
||||
// contactNumber: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: "请输入合同编号",
|
||||
// trigger: "blur"
|
||||
// }
|
||||
// ],
|
||||
companyId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择出租单位',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
customerId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择承租单位',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
const projectName = ref<string>('');
|
||||
const chooseProject = (res) => {
|
||||
// console.log(res)
|
||||
projectName.value = res.projectName;
|
||||
form.projectId = res.projectId;
|
||||
|
||||
companyName.value = res.companyName;
|
||||
form.companyId = res.companyId;
|
||||
|
||||
customerName.value = res.customerName;
|
||||
form.customerId = res.customerId;
|
||||
};
|
||||
|
||||
const companyName = ref<string>();
|
||||
const chooseCompany = (res: Company) => {
|
||||
companyName.value = res.companyName;
|
||||
form.companyId = res.companyId;
|
||||
};
|
||||
|
||||
const customerName = ref<string>('');
|
||||
const chooseCustomer = (res: Customer) => {
|
||||
customerName.value = res.name;
|
||||
form.customerId = res.customerId;
|
||||
form.customerContact = res.contact;
|
||||
};
|
||||
|
||||
const changeInStock = (checked) => {
|
||||
form.isInStock = checked;
|
||||
};
|
||||
|
||||
const changeAutoSettle = (checked) => {
|
||||
form.autoSettle = checked;
|
||||
};
|
||||
|
||||
const fileList = ref<FileItem[]>([]);
|
||||
|
||||
interface FileInfo {
|
||||
file: FileItem;
|
||||
fileList: FileItem[];
|
||||
}
|
||||
|
||||
const onFileUpload = (info: FileInfo) => {
|
||||
let resFileList = [...info.fileList];
|
||||
fileList.value = resFileList.map((file) => {
|
||||
if (file.response) {
|
||||
// Component will show file.url as link
|
||||
file.url = file.response.url;
|
||||
}
|
||||
return file;
|
||||
});
|
||||
};
|
||||
form.fileList = JSON.stringify(fileList.value);
|
||||
};
|
||||
|
||||
const saveFileList = async (contractId) => {
|
||||
contractFileList.value.forEach((item, index) => {
|
||||
contractFileList.value[index].contractId = contractId;
|
||||
});
|
||||
await addBatchContractFile(contractFileList.value);
|
||||
};
|
||||
const contractFileList = ref<ContractFile[]>([]);
|
||||
const uploadFile = (path) => {
|
||||
contractFileList.value.push({
|
||||
path,
|
||||
contractId: 0,
|
||||
userId: loginUser.value.userId
|
||||
});
|
||||
};
|
||||
|
||||
const saveEquipmentList = async (contractId) => {
|
||||
contractEquipmentList.value.forEach((item, index) => {
|
||||
contractEquipmentList.value[index].contractId = contractId;
|
||||
});
|
||||
await addBatchContractEquipment(contractEquipmentList.value);
|
||||
};
|
||||
const delFile = (index) => {
|
||||
contractFileList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const changeEquipment = (equipmentId, index) => {
|
||||
const equip = equipmentList.value.filter(item => item.equipmentId === equipmentId)[0]
|
||||
console.log(equip)
|
||||
contractEquipmentList.value[index].equipmentModel = equip.model
|
||||
contractEquipmentList.value[index].filingNo = equip.filingNo
|
||||
}
|
||||
const getContractFileList = async () => {
|
||||
contractFileList.value = await listContractFile({
|
||||
contractId: props.data?.contractId
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
getEquipmentList();
|
||||
getEquipmentModelList();
|
||||
if (props.data) {
|
||||
const equipmentList = ref<TowerEquipment[]>([]);
|
||||
const getEquipmentList = async () => {
|
||||
equipmentList.value = await listTowerEquipment();
|
||||
};
|
||||
|
||||
const equipmentModelList = ref<TowerModel[]>([]);
|
||||
const getEquipmentModelList = async () => {
|
||||
equipmentModelList.value = await listTowerModel();
|
||||
};
|
||||
|
||||
const contractEquipmentList = ref<ContractEquipment[]>([]);
|
||||
const getContractEquipmentList = async () => {
|
||||
contractEquipmentList.value = await listContractEquipment({
|
||||
contractId: props.data?.contractId
|
||||
});
|
||||
};
|
||||
|
||||
const chooseEquipmentName = (res, index) => {
|
||||
contractEquipmentList.value[index].equipmentName = res.name;
|
||||
};
|
||||
|
||||
const delEquipment = (index) => {
|
||||
contractEquipmentList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const addEquipment = () => {
|
||||
contractEquipmentList.value.push({
|
||||
contractEquipmentId: null,
|
||||
contractId: null,
|
||||
equipmentId: undefined,
|
||||
equipmentName: '',
|
||||
equipmentModel: '',
|
||||
num: null,
|
||||
planRentMonth: null,
|
||||
rentAmount: null,
|
||||
inOutAmount: null,
|
||||
workerAmount: null,
|
||||
otherAmount: null,
|
||||
preBuryAmount: null,
|
||||
remark: null
|
||||
});
|
||||
};
|
||||
|
||||
const { resetFields, validate, validateInfos } = useForm(form, rules);
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
validate()
|
||||
.then(async () => {
|
||||
loading.value = true;
|
||||
// 去除空格
|
||||
form.contactNumber = form.contactNumber?.replace(/\s*/g, '');
|
||||
// 判断权限
|
||||
// if (loginUser.value.roles?.[0].roleCode != 'admin'){
|
||||
// form.status = '1';
|
||||
// }
|
||||
const data = {
|
||||
...form
|
||||
};
|
||||
for (let i = 0; i < contractEquipmentList.value.length; i++) {
|
||||
if (!contractEquipmentList.value[i].equipmentId) {
|
||||
loading.value = false;
|
||||
message.error('请选择设备');
|
||||
return;
|
||||
}
|
||||
if (!contractEquipmentList.value[i].equipmentModel) {
|
||||
loading.value = false;
|
||||
message.error('请选择设备型号');
|
||||
return;
|
||||
}
|
||||
if (!contractEquipmentList.value[i].num) {
|
||||
loading.value = false;
|
||||
message.error('请输入签订数量');
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].planRentMonth === null) {
|
||||
loading.value = false;
|
||||
message.error('请输入计划租期');
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].rentAmount === null) {
|
||||
loading.value = false;
|
||||
message.error('请输入租金');
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].inOutAmount === null) {
|
||||
loading.value = false;
|
||||
message.error('请输入进退场费');
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].workerAmount === null) {
|
||||
loading.value = false;
|
||||
message.error('请输入劳务费用');
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].otherAmount === null) {
|
||||
loading.value = false;
|
||||
message.error('请输入其他费用');
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 转字符串
|
||||
const saveOrUpdate = isUpdate.value ? updateContract : addContract;
|
||||
const res = await saveOrUpdate(data).catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
const contractId = res?.data;
|
||||
// if (contractFileList.value.length > 0) await saveFileList(contractId);
|
||||
if (contractEquipmentList.value.length > 0)
|
||||
await saveEquipmentList(contractId);
|
||||
loading.value = false;
|
||||
assignObject(form, props.data);
|
||||
isUpdate.value = true;
|
||||
getContractFileList();
|
||||
getContractEquipmentList();
|
||||
projectName.value = props.data.projectName;
|
||||
customerName.value = props.data.customerName;
|
||||
companyName.value = props.data.companyName;
|
||||
if (props.data.fileList) {
|
||||
fileList.value = JSON.parse(props.data.fileList);
|
||||
message.success(res?.message);
|
||||
updateVisible(false);
|
||||
emit('done');
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
const saveFileList = async (contractId) => {
|
||||
contractFileList.value.forEach((item, index) => {
|
||||
contractFileList.value[index].contractId = contractId;
|
||||
});
|
||||
await addBatchContractFile(contractFileList.value);
|
||||
};
|
||||
|
||||
const saveEquipmentList = async (contractId) => {
|
||||
contractEquipmentList.value.forEach((item, index) => {
|
||||
contractEquipmentList.value[index].contractId = contractId;
|
||||
});
|
||||
await addBatchContractEquipment(contractEquipmentList.value);
|
||||
};
|
||||
|
||||
const changeEquipment = (equipmentId, index) => {
|
||||
const equip = equipmentList.value.filter(
|
||||
(item) => item.equipmentId === equipmentId
|
||||
)[0];
|
||||
console.log(equip);
|
||||
contractEquipmentList.value[index].equipmentModel = equip.model;
|
||||
contractEquipmentList.value[index].filingNo = equip.filingNo;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
getEquipmentList();
|
||||
getEquipmentModelList();
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(form, props.data);
|
||||
isUpdate.value = true;
|
||||
getContractFileList();
|
||||
getContractEquipmentList();
|
||||
projectName.value = props.data.projectName;
|
||||
customerName.value = props.data.customerName;
|
||||
companyName.value = props.data.companyName;
|
||||
if (props.data.fileList) {
|
||||
fileList.value = JSON.parse(props.data.fileList);
|
||||
}
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
projectName.value = customerName.value = companyName.value = '';
|
||||
contractFileList.value = [];
|
||||
fileList.value = [];
|
||||
resetFields();
|
||||
}
|
||||
} else {
|
||||
projectName.value = customerName.value = companyName.value = "";
|
||||
contractFileList.value = [];
|
||||
fileList.value = [];
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
</script>
|
||||
<style lang="less">
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 1.1rem;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
color: #494949;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 1.1rem;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
color: #494949;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -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