调整
This commit is contained in:
@@ -4,7 +4,7 @@ root = true
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
48
src/App.vue
48
src/App.vue
@@ -11,33 +11,33 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { unref, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import {
|
||||
MAP_KEY,
|
||||
MAP_CODE,
|
||||
LICENSE_CODE,
|
||||
TAB_KEEP_ALIVE
|
||||
} from '@/config/setting';
|
||||
import { useSetDocumentTitle } from '@/utils/document-title-util';
|
||||
import { useLocale } from '@/i18n/use-locale';
|
||||
import { unref, computed } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useThemeStore } from "@/store/modules/theme";
|
||||
import {
|
||||
MAP_KEY,
|
||||
MAP_CODE,
|
||||
LICENSE_CODE,
|
||||
TAB_KEEP_ALIVE
|
||||
} from "@/config/setting";
|
||||
import { useSetDocumentTitle } from "@/utils/document-title-util";
|
||||
import { useLocale } from "@/i18n/use-locale";
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
const { showTabs } = storeToRefs(themeStore);
|
||||
const themeStore = useThemeStore();
|
||||
const { showTabs } = storeToRefs(themeStore);
|
||||
|
||||
// 恢复主题
|
||||
themeStore.recoverTheme();
|
||||
// 恢复主题
|
||||
themeStore.recoverTheme();
|
||||
|
||||
// 切换路由自动更新浏览器页签标题
|
||||
useSetDocumentTitle();
|
||||
// 切换路由自动更新浏览器页签标题
|
||||
useSetDocumentTitle();
|
||||
|
||||
// 国际化配置
|
||||
const { antLocale } = useLocale();
|
||||
// 国际化配置
|
||||
const { antLocale } = useLocale();
|
||||
|
||||
// 用于内链 iframe 组件获取 KeepAlive
|
||||
const keepAlive = computed(() => TAB_KEEP_ALIVE && unref(showTabs));
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: MAP_CODE
|
||||
};
|
||||
// 用于内链 iframe 组件获取 KeepAlive
|
||||
const keepAlive = computed(() => TAB_KEEP_ALIVE && unref(showTabs));
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: MAP_CODE
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -75,6 +75,20 @@ export async function updateCustomer(data: Customer) {
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加客户
|
||||
*/
|
||||
export async function addBatchCustomer(data: Customer[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-customer/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改客户
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { PageParam } from '@/api';
|
||||
import type { Role } from '../../role/model';
|
||||
import type { Menu } from '../../menu/model';
|
||||
import { Company } from '@/api/system/company/model';
|
||||
import type { PageParam } from "@/api";
|
||||
import type { Role } from "../../role/model";
|
||||
import type { Menu } from "../../menu/model";
|
||||
import { Company } from "@/api/system/company/model";
|
||||
|
||||
/**
|
||||
* 用户
|
||||
@@ -37,6 +37,8 @@ export interface User {
|
||||
introduction?: string;
|
||||
// 机构id
|
||||
organizationId?: number;
|
||||
// 用户等级
|
||||
userLevel?: number;
|
||||
// 状态, 0正常, 1冻结
|
||||
status?: number;
|
||||
// 性别名称
|
||||
@@ -98,3 +100,5 @@ export interface UserParam extends PageParam {
|
||||
roleId?: string;
|
||||
isStaff?: boolean;
|
||||
}
|
||||
|
||||
export const USER_LEVEL_LIST = ["无权限", "场地主管", "资料员", "经营人员", "生产主管", "审核人", "资产员", "车辆调度员", "维保人员", "财务"];
|
||||
|
||||
@@ -1,40 +1,43 @@
|
||||
import type { PageParam } from '@/api';
|
||||
import type { PageParam } from "@/api";
|
||||
import { Dayjs } from "dayjs";
|
||||
|
||||
export interface Accessory {
|
||||
accessoryId?: undefined;
|
||||
accessoryName?: string;
|
||||
accessoryNo?: string;
|
||||
accessoryCategory?: object;
|
||||
accessoryModel?: string;
|
||||
accessoryModelMultiple?: string[];
|
||||
accessorySpecs?: string;
|
||||
accessoryPrice?: number;
|
||||
accessoryUnit?: string;
|
||||
accessoryStock?: string;
|
||||
companyNo?: string;
|
||||
companyName?: string;
|
||||
manufactor?: string;
|
||||
manufactorNo?: string;
|
||||
accessoryWeight?: string;
|
||||
lifeYear?: number;
|
||||
factoryDate?: string;
|
||||
scrapDate?: string;
|
||||
status?: number;
|
||||
comments?: string;
|
||||
sortNumber?: number;
|
||||
userId?: number;
|
||||
deleted?: number;
|
||||
tenantId?: number;
|
||||
createTime?: string;
|
||||
updateTime?: string;
|
||||
accessoryId?: undefined;
|
||||
accessoryName?: string;
|
||||
accessoryNo?: string;
|
||||
accessoryCategory?: object;
|
||||
accessoryModel?: string;
|
||||
accessoryModelMultiple?: string[];
|
||||
accessorySpecs?: string;
|
||||
accessoryPrice?: number;
|
||||
accessoryNum?: number;
|
||||
accessoryUnit?: string;
|
||||
accessoryStock?: string;
|
||||
companyNo?: string;
|
||||
companyName?: string;
|
||||
manufactor?: string;
|
||||
manufactorNo?: string;
|
||||
accessoryWeight?: string;
|
||||
lifeYear?: number;
|
||||
factoryDate?: string;
|
||||
scrapDate?: string;
|
||||
status?: number;
|
||||
comments?: string;
|
||||
sortNumber?: number;
|
||||
userId?: number;
|
||||
deleted?: number;
|
||||
tenantId?: number;
|
||||
createTime?: string;
|
||||
updateTime?: string;
|
||||
buyDate?: string | Dayjs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索条件
|
||||
*/
|
||||
export interface AccessoryParam extends PageParam {
|
||||
accessoryId?: number;
|
||||
accessoryName?: string;
|
||||
status?: number;
|
||||
keywords?: string;
|
||||
accessoryId?: number;
|
||||
accessoryName?: string;
|
||||
status?: number;
|
||||
keywords?: string;
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ export interface Contract {
|
||||
// 合同编号
|
||||
contactNumber?: string;
|
||||
// 签订日期
|
||||
signDate?: string;
|
||||
signDate?: any;
|
||||
// 开始日期
|
||||
startDate?: string;
|
||||
startDate?: any;
|
||||
// 截止日期
|
||||
endDate?: string;
|
||||
endDate?: any;
|
||||
// 合同金额
|
||||
contractAmount?: number;
|
||||
// 合同约定金额
|
||||
@@ -31,13 +31,20 @@ export interface Contract {
|
||||
// 是否自动结算
|
||||
autoSettle?: number;
|
||||
// 结算方式
|
||||
settleMethod?: number;
|
||||
settleMethod?: any;
|
||||
// 跨月结算日期
|
||||
extendMonthDate?: number;
|
||||
userId?: any;
|
||||
projectName?: any;
|
||||
customerName?: any;
|
||||
companyName?: any;
|
||||
totalInvoicingAmount?: any;
|
||||
totalIncomeAmount?: any;
|
||||
totalReceivableAmount?: any;
|
||||
totalSettleAmount?: any;
|
||||
payRate?: any;
|
||||
remark?: string;
|
||||
fileList?: string;
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +53,7 @@ export interface Contract {
|
||||
*/
|
||||
export interface ContractParam extends PageParam {
|
||||
contactNumber?: string;
|
||||
projectName?: string;
|
||||
createTimeStart?: string;
|
||||
createTimeEnd?: string;
|
||||
betweenTime?: any;
|
||||
|
||||
@@ -8,9 +8,15 @@ export interface ContractEquipment {
|
||||
// 合同id
|
||||
contractId: any;
|
||||
// 设备名
|
||||
equipmentId: any;
|
||||
equipmentName: string;
|
||||
name?: string;
|
||||
model?: string;
|
||||
// 规格
|
||||
equipmentModel: string;
|
||||
equipmentModel?: string;
|
||||
factoryNo?: string;
|
||||
equipmentNo?: string;
|
||||
filingNo?: string;
|
||||
// 数量
|
||||
num: any;
|
||||
// 租期
|
||||
@@ -35,5 +41,5 @@ export interface ContractEquipment {
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface ContractEquipmentParam extends PageParam {
|
||||
contactId?: string;
|
||||
contractId?: string;
|
||||
}
|
||||
|
||||
@@ -20,5 +20,5 @@ export interface ContractFile {
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface ContractFileParam extends PageParam {
|
||||
contactId?: string;
|
||||
contractId?: string;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { PageParam } from '@/api';
|
||||
*/
|
||||
export interface ContractSettleEquipment {
|
||||
contractSettleId?: any;
|
||||
equipmentId: any;
|
||||
// 合同id
|
||||
contractId: any;
|
||||
// 设备名
|
||||
@@ -13,6 +14,8 @@ export interface ContractSettleEquipment {
|
||||
equipmentModel: string;
|
||||
// 进场编号
|
||||
factoryNo: any;
|
||||
// 备案号
|
||||
filingNo: any;
|
||||
// 自编号
|
||||
equipmentNo: any;
|
||||
// 租期
|
||||
@@ -25,10 +28,15 @@ export interface ContractSettleEquipment {
|
||||
workerAmount: any;
|
||||
// 其他费用
|
||||
otherAmount: any;
|
||||
// 其他费用计算模式
|
||||
otherAmountCalMode: any;
|
||||
// 预埋费
|
||||
preBuryAmount: any;
|
||||
// 备注
|
||||
remark?: any;
|
||||
userId?: any;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,19 @@ import type {
|
||||
TowerEquipment,
|
||||
TowerEquipmentParam
|
||||
} from '@/api/tower/equipment/model';
|
||||
/**
|
||||
* 设备数据
|
||||
*/
|
||||
export async function towerEquipmentData() {
|
||||
const res = await request.get(
|
||||
'/tower/tower-equipment/data'
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询设备
|
||||
*/
|
||||
@@ -134,3 +147,16 @@ export async function removeBatchTowerEquipment(data: (number | undefined)[]) {
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
export async function towerEquipmentQr(params: TowerEquipmentParam) {
|
||||
const res = await request.get<ApiResult<unknown>>(
|
||||
'/tower/tower-equipment/qr',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
@@ -1,55 +1,61 @@
|
||||
import type { PageParam } from '@/api';
|
||||
import type { PageParam } from "@/api";
|
||||
import { Project } from "@/api/tower/project/model";
|
||||
|
||||
export interface TowerEquipment {
|
||||
equipmentId?: number;
|
||||
name?: string;
|
||||
model?: string;
|
||||
equipmentNo?: string;
|
||||
factoryNo?: string;
|
||||
factoryDate?: string;
|
||||
manufactor?: string;
|
||||
lifeYear?: number;
|
||||
surplusYear?: number;
|
||||
scrapDate?: string;
|
||||
beianNo?: string;
|
||||
licenceNo?: string;
|
||||
company?: string;
|
||||
organization?: string;
|
||||
warehouse?: string;
|
||||
source?: string;
|
||||
filingNo?: string;
|
||||
machineNo?: string;
|
||||
maxLiftingHeight?: string;
|
||||
armLength?: string;
|
||||
isOutOrg?: boolean;
|
||||
buyDate?: string;
|
||||
currentLocation?: string;
|
||||
designHeight?: number;
|
||||
height?: number;
|
||||
ratedLoad?: string;
|
||||
files?: string;
|
||||
file1?: string;
|
||||
file2?: string;
|
||||
file3?: string;
|
||||
file4?: string;
|
||||
file5?: string;
|
||||
file6?: string;
|
||||
file7?: string;
|
||||
users?: string;
|
||||
status?: number;
|
||||
comments?: string;
|
||||
userId?: number;
|
||||
deleted?: number;
|
||||
tenantId?: number;
|
||||
createTime?: number;
|
||||
maxRatedLoad?: string;
|
||||
equipmentId?: number;
|
||||
name?: string;
|
||||
model?: string;
|
||||
equipmentNo?: string;
|
||||
factoryNo?: string;
|
||||
factoryDate?: string;
|
||||
manufactor?: string;
|
||||
lifeYear?: any;
|
||||
surplusYear?: number;
|
||||
scrapDate?: string;
|
||||
beianNo?: string;
|
||||
licenceNo?: string;
|
||||
company?: string;
|
||||
organization?: string;
|
||||
warehouse?: string;
|
||||
source?: string;
|
||||
filingNo?: string;
|
||||
machineNo?: string;
|
||||
maxLiftingHeight?: string;
|
||||
armLength?: string;
|
||||
isOutOrg?: boolean;
|
||||
buyDate?: string;
|
||||
currentLocation?: string;
|
||||
designHeight?: number;
|
||||
height?: number;
|
||||
ratedLoad?: string;
|
||||
files?: string;
|
||||
file1?: string;
|
||||
file2?: string;
|
||||
file3?: string;
|
||||
file4?: string;
|
||||
file5?: string;
|
||||
file6?: string;
|
||||
file7?: string;
|
||||
users?: string;
|
||||
status?: number;
|
||||
comments?: string;
|
||||
userId?: number;
|
||||
deleted?: number;
|
||||
tenantId?: number;
|
||||
createTime?: number;
|
||||
maxRatedLoad?: string;
|
||||
securityStatus?: string;
|
||||
projectName?: string;
|
||||
competentDepartment?: string;
|
||||
projectList?: Project[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索条件
|
||||
*/
|
||||
export interface TowerEquipmentParam extends PageParam {
|
||||
equipmentId?: number;
|
||||
name?: string;
|
||||
status?: number;
|
||||
equipmentId?: number;
|
||||
name?: string;
|
||||
status?: number;
|
||||
yearFilter?: number;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ export interface TowerFall {
|
||||
factory?: string;
|
||||
factoryDate?: string;
|
||||
discardDate?: string;
|
||||
|
||||
checkDate?: string;
|
||||
file1?: string;
|
||||
file2?: string;
|
||||
file3?: string;
|
||||
|
||||
129
src/api/tower/finalSettle/index.ts
Normal file
129
src/api/tower/finalSettle/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type {ApiResult, PageResult} from '@/api';
|
||||
import type {FinalSettle, FinalSettleParam} from './model';
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageFinalSettle(params: FinalSettleParam) {
|
||||
const res = await request.get<ApiResult<PageResult<FinalSettle>>>(
|
||||
'/tower/tower-contract-final-settle/page',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listFinalSettle(params?: FinalSettleParam) {
|
||||
const res = await request.get<ApiResult<FinalSettle[]>>(
|
||||
'/tower/tower-contract-final-settle',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getFinalSettle(id: number) {
|
||||
const res = await request.get<ApiResult<FinalSettle>>(
|
||||
'/tower/tower-contract-final-settle/' + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addFinalSettle(data: FinalSettle) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateFinalSettle(data: FinalSettle) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchFinalSettle(data: FinalSettle[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchFinalSettle(data: FinalSettle[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeFinalSettle(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle/' + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchFinalSettle(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle/batch',
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
31
src/api/tower/finalSettle/model/index.ts
Normal file
31
src/api/tower/finalSettle/model/index.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface FinalSettle {
|
||||
contractFinalSettleId?: any;
|
||||
contractId?: any;
|
||||
settleCompanyId?: any;
|
||||
fileList?: any;
|
||||
signName?: any;
|
||||
signDate?: any;
|
||||
remark?: any;
|
||||
userId?: any;
|
||||
settleCompanyName?: any;
|
||||
contractNumber?: any;
|
||||
companyName?: any;
|
||||
customerName?: any;
|
||||
projectName?: any;
|
||||
totalSettleAmount?: any;
|
||||
totalInvoicingAmount?: any;
|
||||
totalIncomeAmount?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface FinalSettleParam extends PageParam {
|
||||
projectName?: string;
|
||||
contractNo?: string;
|
||||
}
|
||||
129
src/api/tower/finalSettleLost/index.ts
Normal file
129
src/api/tower/finalSettleLost/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type {ApiResult, PageResult} from '@/api';
|
||||
import type {FinalSettleLost, FinalSettleLostParam} from './model';
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageFinalSettleLost(params: FinalSettleLostParam) {
|
||||
const res = await request.get<ApiResult<PageResult<FinalSettleLost>>>(
|
||||
'/tower/tower-contract-final-settle-lost/page',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listFinalSettleLost(params?: FinalSettleLostParam) {
|
||||
const res = await request.get<ApiResult<FinalSettleLost[]>>(
|
||||
'/tower/tower-contract-final-settle-lost',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getFinalSettleLost(id: number) {
|
||||
const res = await request.get<ApiResult<FinalSettleLost>>(
|
||||
'/tower/tower-contract-final-settle-lost/' + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addFinalSettleLost(data: FinalSettleLost) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle-lost',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateFinalSettleLost(data: FinalSettleLost) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle-lost',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchFinalSettleLost(data: FinalSettleLost[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle-lost/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchFinalSettleLost(data: FinalSettleLost[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle-lost/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeFinalSettleLost(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle-lost/' + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchFinalSettleLost(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-contract-final-settle-lost/batch',
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
22
src/api/tower/finalSettleLost/model/index.ts
Normal file
22
src/api/tower/finalSettleLost/model/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface FinalSettleLost {
|
||||
finalSettleLostId?: any;
|
||||
finalSettleId?: any;
|
||||
itemId?: any;
|
||||
itemName?: any;
|
||||
amount?: any;
|
||||
num?: any;
|
||||
total?: any;
|
||||
userId?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface FinalSettleLostParam extends PageParam {
|
||||
finalSettleId?: string;
|
||||
}
|
||||
129
src/api/tower/income/index.ts
Normal file
129
src/api/tower/income/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type {ApiResult, PageResult} from '@/api';
|
||||
import type {Income, IncomeParam} from './model';
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageIncome(params: IncomeParam) {
|
||||
const res = await request.get<ApiResult<PageResult<Income>>>(
|
||||
'/tower/tower-income/page',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listIncome(params?: IncomeParam) {
|
||||
const res = await request.get<ApiResult<Income[]>>(
|
||||
'/tower/tower-income',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getIncome(id: number) {
|
||||
const res = await request.get<ApiResult<Income>>(
|
||||
'/tower/tower-income/' + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addIncome(data: Income) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-income',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateIncome(data: Income) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-income',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchIncome(data: Income[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-income/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchIncome(data: Income[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-income/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeIncome(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-income/' + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchIncome(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-income/batch',
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
43
src/api/tower/income/model/index.ts
Normal file
43
src/api/tower/income/model/index.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface Income {
|
||||
incomeId?: any;
|
||||
contractId?: any;
|
||||
incomeNo?: any;
|
||||
incomeDate?: any;
|
||||
incomeCompanyId?: any;
|
||||
payCompanyId?: any;
|
||||
payCompanyName?: any;
|
||||
amount?: any;
|
||||
companyName?: any;
|
||||
totalIncomeAmount?: any;
|
||||
totalInvoicingAmount?: any;
|
||||
incomeType?: any;
|
||||
expectIncomeDate?: any;
|
||||
expectIncomeAmount?: any;
|
||||
incomeMethod?: any;
|
||||
invoicingNo?: any;
|
||||
fileList?: any;
|
||||
remark?: any;
|
||||
status?: any;
|
||||
userId?: any;
|
||||
signName?: any;
|
||||
signDate?: any;
|
||||
contractNumber?: any;
|
||||
projectName?: any;
|
||||
incomeCompanyName?: any;
|
||||
customerName?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface IncomeParam extends PageParam {
|
||||
projectName?: string;
|
||||
contractNo?: string;
|
||||
}
|
||||
|
||||
export const INCOME_STATUS_LIST = ['已收款', '已作废']
|
||||
129
src/api/tower/incomeEquipment/index.ts
Normal file
129
src/api/tower/incomeEquipment/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type {ApiResult, PageResult} from '@/api';
|
||||
import type {IncomeEquipment, IncomeEquipmentParam} from './model';
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageIncomeEquipment(params: IncomeEquipmentParam) {
|
||||
const res = await request.get<ApiResult<PageResult<IncomeEquipment>>>(
|
||||
'/tower/tower-income-equipment/page',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listIncomeEquipment(params?: IncomeEquipmentParam) {
|
||||
const res = await request.get<ApiResult<IncomeEquipment[]>>(
|
||||
'/tower/tower-income-equipment',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getIncomeEquipment(id: number) {
|
||||
const res = await request.get<ApiResult<IncomeEquipment>>(
|
||||
'/tower/tower-income-equipment/' + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addIncomeEquipment(data: IncomeEquipment) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-income-equipment',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateIncomeEquipment(data: IncomeEquipment) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-income-equipment',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchIncomeEquipment(data: IncomeEquipment[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-income-equipment/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchIncomeEquipment(data: IncomeEquipment[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-income-equipment/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeIncomeEquipment(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-income-equipment/' + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchIncomeEquipment(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-income-equipment/batch',
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
30
src/api/tower/incomeEquipment/model/index.ts
Normal file
30
src/api/tower/incomeEquipment/model/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface IncomeEquipment {
|
||||
incomeEquipmentId?: any;
|
||||
incomeId?: any;
|
||||
equipmentId?: any;
|
||||
equipmentName?: any;
|
||||
equipmentModel?: any;
|
||||
// 进场编号
|
||||
factoryNo?: any;
|
||||
// 自编号
|
||||
equipmentNo?: any;
|
||||
filingNo?: string;
|
||||
rentAmount?: string;
|
||||
shareAmount?: any;
|
||||
userId?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface IncomeEquipmentParam extends PageParam {
|
||||
projectName?: string;
|
||||
contractNo?: string;
|
||||
incomeId?: string;
|
||||
}
|
||||
|
||||
129
src/api/tower/invoicing/index.ts
Normal file
129
src/api/tower/invoicing/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type {ApiResult, PageResult} from '@/api';
|
||||
import type {Invoicing, InvoicingParam} from './model';
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageInvoicing(params: InvoicingParam) {
|
||||
const res = await request.get<ApiResult<PageResult<Invoicing>>>(
|
||||
'/tower/tower-invoicing/page',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listInvoicing(params?: InvoicingParam) {
|
||||
const res = await request.get<ApiResult<Invoicing[]>>(
|
||||
'/tower/tower-invoicing',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getInvoicing(id: number) {
|
||||
const res = await request.get<ApiResult<Invoicing>>(
|
||||
'/tower/tower-invoicing/' + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addInvoicing(data: Invoicing) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateInvoicing(data: Invoicing) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchInvoicing(data: Invoicing[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchInvoicing(data: Invoicing[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeInvoicing(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing/' + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchInvoicing(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing/batch',
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
35
src/api/tower/invoicing/model/index.ts
Normal file
35
src/api/tower/invoicing/model/index.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface Invoicing {
|
||||
invoicingId?: any;
|
||||
contractId?: any;
|
||||
invoicingDate?: any;
|
||||
invoicingCompany?: any;
|
||||
requestName?: any;
|
||||
signName?: any;
|
||||
invoicingAmount?: any;
|
||||
invoicingNo?: any;
|
||||
fileList?: any;
|
||||
remark?: any;
|
||||
status?: any;
|
||||
userId?: any;
|
||||
contractNumber?: any;
|
||||
projectName?: any;
|
||||
signDate?: any;
|
||||
companyName?: any;
|
||||
customerName?: any;
|
||||
totalInvoicingAmount?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface InvoicingParam extends PageParam {
|
||||
projectName?: string;
|
||||
contractNo?: string;
|
||||
}
|
||||
|
||||
export const INVOICING_STATUS_LIST = ['已开票', '已作废']
|
||||
129
src/api/tower/invoicingSettle/index.ts
Normal file
129
src/api/tower/invoicingSettle/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type {ApiResult, PageResult} from '@/api';
|
||||
import type {InvoicingSettle, InvoicingSettleParam} from './model';
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageInvoicingSettle(params: InvoicingSettleParam) {
|
||||
const res = await request.get<ApiResult<PageResult<InvoicingSettle>>>(
|
||||
'/tower/tower-invoicing-settle/page',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listInvoicingSettle(params?: InvoicingSettleParam) {
|
||||
const res = await request.get<ApiResult<InvoicingSettle[]>>(
|
||||
'/tower/tower-invoicing-settle',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getInvoicingSettle(id: number) {
|
||||
const res = await request.get<ApiResult<InvoicingSettle>>(
|
||||
'/tower/tower-invoicing-settle/' + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addInvoicingSettle(data: InvoicingSettle) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing-settle',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateInvoicingSettle(data: InvoicingSettle) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing-settle',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchInvoicingSettle(data: InvoicingSettle[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing-settle/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchInvoicingSettle(data: InvoicingSettle[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing-settle/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeInvoicingSettle(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-InvoicingSettle/' + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchInvoicingSettle(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-invoicing-settle/batch',
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
21
src/api/tower/invoicingSettle/model/index.ts
Normal file
21
src/api/tower/invoicingSettle/model/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface InvoicingSettle {
|
||||
invoicingSettleId?: any;
|
||||
invoicingId?: any;
|
||||
settleId?: any;
|
||||
shareAmount?: any;
|
||||
settleNumber?: any;
|
||||
startDate?: any;
|
||||
settleAmount?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface InvoicingSettleParam extends PageParam {
|
||||
invoicingId?: string;
|
||||
}
|
||||
129
src/api/tower/lending/index.ts
Normal file
129
src/api/tower/lending/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type {ApiResult, PageResult} from '@/api';
|
||||
import type {Lending, LendingParam} from './model';
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageLending(params: LendingParam) {
|
||||
const res = await request.get<ApiResult<PageResult<Lending>>>(
|
||||
'/tower/tower-lending/page',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listLending(params?: LendingParam) {
|
||||
const res = await request.get<ApiResult<Lending[]>>(
|
||||
'/tower/tower-lending',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getLending(id: number) {
|
||||
const res = await request.get<ApiResult<Lending>>(
|
||||
'/tower/tower-lending/' + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addLending(data: Lending) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-lending',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateLending(data: Lending) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-lending',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchLending(data: Lending[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-lending/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchLending(data: Lending[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-lending/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeLending(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-lending/' + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchLending(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-lending/batch',
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
28
src/api/tower/lending/model/index.ts
Normal file
28
src/api/tower/lending/model/index.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface Lending {
|
||||
lendingId?: any;
|
||||
contractId?: any;
|
||||
contactNumber?: any;
|
||||
signDate?: any;
|
||||
projectName?: any;
|
||||
customerName?: any;
|
||||
companyName?: any;
|
||||
propertyCompany?: any;
|
||||
settleDate?: any;
|
||||
settleAmount?: any;
|
||||
fileList?: any;
|
||||
remark?: any;
|
||||
userId?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface LendingParam extends PageParam {
|
||||
projectName?: string;
|
||||
contractNo?: string;
|
||||
}
|
||||
129
src/api/tower/lendingSettle/index.ts
Normal file
129
src/api/tower/lendingSettle/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import request from '@/utils/request';
|
||||
import type {ApiResult, PageResult} from '@/api';
|
||||
import type {LendingSettle, LendingSettleParam} from './model';
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageLendingSettle(params: LendingSettleParam) {
|
||||
const res = await request.get<ApiResult<PageResult<LendingSettle>>>(
|
||||
'/tower/tower-lending-settle/page',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listLendingSettle(params?: LendingSettleParam) {
|
||||
const res = await request.get<ApiResult<LendingSettle[]>>(
|
||||
'/tower/tower-lending-settle',
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getLendingSettle(id: number) {
|
||||
const res = await request.get<ApiResult<LendingSettle>>(
|
||||
'/tower/tower-lending-settle/' + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addLendingSettle(data: LendingSettle) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-lending-settle',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateLendingSettle(data: LendingSettle) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-lending-settle',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchLending(data: LendingSettle[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
'/tower/tower-lending-settle/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchLendingSettle(data: LendingSettle[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-lending-settle/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeLendingSettle(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-lending-settle/' + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchLendingSettle(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
'/tower/tower-lending-settle/batch',
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
40
src/api/tower/lendingSettle/model/index.ts
Normal file
40
src/api/tower/lendingSettle/model/index.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import type { PageParam } from '@/api';
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface LendingSettle {
|
||||
lendingSettleListId?: any;
|
||||
lendingId?: any;
|
||||
equipmentId?: any;
|
||||
lendingPath?: any;
|
||||
coopWay?: any;
|
||||
startDate?: any;
|
||||
stopDate?: any;
|
||||
calDay?: any;
|
||||
isFullMonth?: any;
|
||||
daysInMonth?: any;
|
||||
monthRentAmount?: any;
|
||||
shouldPayRentAmount?: any;
|
||||
dailyRentAmount?: any;
|
||||
shouldSupplementAmount?: any;
|
||||
shouldDeductionAmount?: any;
|
||||
paidAmount?: any;
|
||||
taxRate?: any;
|
||||
taxAmount?: any;
|
||||
totalAmountWithTax?: any;
|
||||
remark?: any;
|
||||
userId?: any;
|
||||
equipmentName?: any;
|
||||
equipmentModel?: any;
|
||||
equipmentNo?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface LendingSettleParam extends PageParam {
|
||||
projectName?: string;
|
||||
contractNo?: string;
|
||||
lendingId?: string;
|
||||
}
|
||||
@@ -1,6 +1,19 @@
|
||||
import request from '@/utils/request';
|
||||
import type { ApiResult, PageResult } from '@/api';
|
||||
import type { Project, ProjectParam } from '@/api/tower/project/model';
|
||||
|
||||
/**
|
||||
* 项目数据
|
||||
*/
|
||||
export async function towerProjectData() {
|
||||
const res = await request.get(
|
||||
'/tower/tower-project/data'
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
/**
|
||||
* 分页查询仓库
|
||||
*/
|
||||
@@ -43,6 +56,16 @@ export async function addProject(data: Project) {
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
export async function addBatchProject(data: Project[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
'/tower/tower-project/batch',
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改仓库
|
||||
|
||||
@@ -17,11 +17,16 @@ export interface Project {
|
||||
projectId?: number;
|
||||
projectName?: string;
|
||||
projectImage?: string;
|
||||
filingNo?: string;
|
||||
files?: FileItem[];
|
||||
companyName?: string;
|
||||
companyId?: number;
|
||||
customerName?: string;
|
||||
customerId?: number;
|
||||
projectRegion?: string;
|
||||
placeList?: string;
|
||||
projectAddress?: string;
|
||||
projectCity?: string;
|
||||
longitude?: string;
|
||||
latitude?: string;
|
||||
superviseNo?: string;
|
||||
|
||||
@@ -6,9 +6,12 @@ import type { PageParam } from '@/api';
|
||||
export interface ProjectOrder {
|
||||
// 合同预定设备清单id
|
||||
projectOrderId?: number;
|
||||
equipmentId?: number;
|
||||
equipmentName?: string;
|
||||
equipmentModel?: string;
|
||||
equipmentNum?: number;
|
||||
filingNo?: string;
|
||||
factoryNo?: string;
|
||||
key?: string;
|
||||
unit?: string;
|
||||
startTime?: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PageParam } from '@/api';
|
||||
import type { PageParam } from "@/api";
|
||||
|
||||
/**
|
||||
* 合同
|
||||
@@ -9,12 +9,13 @@ export interface Settle {
|
||||
status?: any;
|
||||
contractId?: any;
|
||||
startDate?: any;
|
||||
endDate?: string;
|
||||
settleMethod?: number;
|
||||
endDate?: any;
|
||||
settleMethod?: any;
|
||||
extendMonthDate?: number;
|
||||
totalAmount?: number;
|
||||
userId?: any;
|
||||
contactNumber?: any;
|
||||
projectName?: any;
|
||||
|
||||
}
|
||||
|
||||
@@ -25,3 +26,5 @@ export interface SettleParam extends PageParam {
|
||||
settleNo?: string;
|
||||
contractId?: string;
|
||||
}
|
||||
|
||||
export const SETTLE_STATUS_LIST = ["未认证", "已认证", "已失效"];
|
||||
|
||||
@@ -22,6 +22,12 @@ export interface SettleDetail {
|
||||
userId?: any;
|
||||
days?: any;
|
||||
dailyAmount?: any;
|
||||
month?: any;
|
||||
day?: any;
|
||||
payRate?: any;
|
||||
inDate?: any;
|
||||
outDate?: any;
|
||||
realAmount?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
143
src/api/tower/worksheet/index.ts
Normal file
143
src/api/tower/worksheet/index.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import request from "@/utils/request";
|
||||
import type { ApiResult, PageResult } from "@/api";
|
||||
import type { Worksheet, WorksheetParam } from "./model";
|
||||
|
||||
/**
|
||||
* 分页查询结算
|
||||
*/
|
||||
export async function pageWorksheet(params: WorksheetParam) {
|
||||
const res = await request.get<ApiResult<PageResult<Worksheet>>>(
|
||||
"/tower/tower-worksheet/page",
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同列表
|
||||
*/
|
||||
export async function listWorksheet(params?: WorksheetParam) {
|
||||
const res = await request.get<ApiResult<Worksheet[]>>(
|
||||
"/tower/tower-worksheet",
|
||||
{
|
||||
params
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getWorksheet(id: number) {
|
||||
const res = await request.get<ApiResult<Worksheet>>(
|
||||
"/tower/tower-worksheet/" + id
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询合同
|
||||
*/
|
||||
export async function getWorksheetByWordType(projectId: number, workType: number) {
|
||||
const res = await request.post<ApiResult<Worksheet[]>>(
|
||||
"/tower/tower-worksheet/by-work-type", { projectId, workType }
|
||||
);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加合同
|
||||
*/
|
||||
export async function addWorksheet(data: Worksheet) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
"/tower/tower-worksheet",
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改合同
|
||||
*/
|
||||
export async function updateWorksheet(data: Worksheet) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
"/tower/tower-worksheet",
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改合同
|
||||
*/
|
||||
export async function updateBatchWorksheet(data: Worksheet[]) {
|
||||
const res = await request.put<ApiResult<unknown>>(
|
||||
"/tower/tower-worksheet/batch",
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
export async function addBatchWorksheet(data: Worksheet[]) {
|
||||
const res = await request.post<ApiResult<unknown>>(
|
||||
"/tower/tower-worksheet/batch",
|
||||
data
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同
|
||||
*/
|
||||
export async function removeWorksheet(id?: number) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
"/tower/tower-worksheet/" + id
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除合同
|
||||
*/
|
||||
export async function removeBatchWorksheet(data: (number | undefined)[]) {
|
||||
const res = await request.delete<ApiResult<unknown>>(
|
||||
"/tower/tower-worksheet/batch",
|
||||
{
|
||||
data
|
||||
}
|
||||
);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
66
src/api/tower/worksheet/model/index.ts
Normal file
66
src/api/tower/worksheet/model/index.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import type { PageParam } from "@/api";
|
||||
import { User } from "@/api/system/user/model";
|
||||
|
||||
/**
|
||||
* 合同
|
||||
*/
|
||||
export interface Worksheet {
|
||||
worksheetId?: any;
|
||||
type?: any;
|
||||
startUid?: any;
|
||||
projectId?: any;
|
||||
planInDate?: any;
|
||||
receiveDate?: any;
|
||||
equipmentType?: any;
|
||||
workType?: any;
|
||||
auditStatus?: number;
|
||||
status?: number;
|
||||
detail?: any;
|
||||
setUp?: any;
|
||||
parts?: any;
|
||||
check?: any;
|
||||
projectName?: any;
|
||||
projectRegion?: any;
|
||||
projectAddress?: string;
|
||||
address?: string;
|
||||
contactPhone?: any;
|
||||
productionMangerUser?: User;
|
||||
documentUser?: User;
|
||||
classManagerUser?: User;
|
||||
assetUser?: User;
|
||||
fixUser?: User;
|
||||
carDispatchUser?: User;
|
||||
auditList?: any[];
|
||||
carDispatchList?: any[];
|
||||
documentDoneTime?:string,
|
||||
assetDoneTime?:string,
|
||||
fixDoneTime?:string,
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同搜索条件
|
||||
*/
|
||||
export interface WorksheetParam extends PageParam {
|
||||
projectName?: string;
|
||||
contractNo?: string;
|
||||
}
|
||||
|
||||
export const WORKSHEET_STATUS_LIST = [
|
||||
"已取消",
|
||||
"待派单",
|
||||
"待整理资料",
|
||||
"待到场",
|
||||
"待确认",
|
||||
"已完成"
|
||||
];
|
||||
|
||||
export const WORKSHEET_EQUIPMENT_TYPE = ["塔式起重机", "施工升降机", "物料提升机"];
|
||||
export const WORKSHEET_WORK_TYPE = ["安装单", "加高单", "拆卸单"];
|
||||
|
||||
export const WORKSHEET_AUDIT_STATUS_LIST = [
|
||||
"无需审核",
|
||||
"待审核",
|
||||
"审核通过",
|
||||
"审核解决",
|
||||
]
|
||||
|
||||
@@ -89,7 +89,7 @@ const columns = ref<ColumnItem[]>([
|
||||
},
|
||||
{
|
||||
title: "合同编号",
|
||||
dataIndex: "contractNumber"
|
||||
dataIndex: "contactNumber"
|
||||
},
|
||||
{
|
||||
title: "项目名称",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="750"
|
||||
width="50%"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
:title="title"
|
||||
@@ -17,14 +17,17 @@
|
||||
:pagination="false"
|
||||
>
|
||||
<template #toolbar>
|
||||
<a-input-search
|
||||
allow-clear
|
||||
v-model:value="searchText"
|
||||
placeholder="请输入搜索关键词"
|
||||
style="width: 200px"
|
||||
@search="reload"
|
||||
@pressEnter="reload"
|
||||
/>
|
||||
<a-space>
|
||||
<a-input-search
|
||||
allow-clear
|
||||
v-model:value="searchText"
|
||||
placeholder="请输入搜索关键词"
|
||||
style="width: 200px"
|
||||
@search="reload"
|
||||
@pressEnter="reload"
|
||||
/>
|
||||
<a-checkbox v-model:checked="idleOnly" @change="reload">仅显示未绑定项目设备</a-checkbox>
|
||||
</a-space>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
@@ -38,124 +41,121 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import {
|
||||
ColumnItem,
|
||||
DatasourceFunction
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { EleProTable } from 'ele-admin-pro';
|
||||
import { TowerEquipment, TowerEquipmentParam } from "@/api/tower/equipment/model";
|
||||
import { pageTowerEquipment } from "@/api/tower/equipment";
|
||||
import { ref } from "vue";
|
||||
import {
|
||||
ColumnItem,
|
||||
DatasourceFunction
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { EleProTable } from "ele-admin-pro";
|
||||
import { TowerEquipment, TowerEquipmentParam } from "@/api/tower/equipment/model";
|
||||
import { pageTowerEquipment } from "@/api/tower/equipment";
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 标题
|
||||
title?: string;
|
||||
// 修改回显的数据
|
||||
data?: TowerEquipment | null;
|
||||
}>();
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 标题
|
||||
title?: string;
|
||||
// 修改回显的数据
|
||||
data?: TowerEquipment | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done', data: TowerEquipment): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: "done", data: TowerEquipment): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 搜索内容
|
||||
const searchText = ref(null);
|
||||
// 搜索内容
|
||||
const searchText = ref(null);
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id'
|
||||
},
|
||||
{
|
||||
title: '设备名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '设备型号',
|
||||
key: 'model',
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '出场编号',
|
||||
dataIndex: 'factoryNo',
|
||||
key: 'factoryNo',
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '设备编号',
|
||||
dataIndex: 'equipmentNo',
|
||||
key: 'equipmentNo',
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '制造单位',
|
||||
dataIndex: 'manufactor',
|
||||
key: 'manufactor',
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '产权单位',
|
||||
dataIndex: 'company',
|
||||
key: 'company',
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
align: 'center'
|
||||
// 表格配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: "设备名称",
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: "设备型号",
|
||||
dataIndex: "model",
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: "出场编号",
|
||||
dataIndex: "factoryNo",
|
||||
key: "factoryNo",
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: "设备编号",
|
||||
dataIndex: "equipmentNo",
|
||||
key: "equipmentNo",
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: "备案编号",
|
||||
dataIndex: "filingNo",
|
||||
key: "filingNo",
|
||||
showSorterTooltip: false
|
||||
},
|
||||
{
|
||||
title: "制造单位",
|
||||
dataIndex: "manufactor",
|
||||
key: "manufactor",
|
||||
showSorterTooltip: false,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center"
|
||||
}
|
||||
]);
|
||||
|
||||
const idleOnly = ref<boolean>(false)
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||
where = {};
|
||||
// 搜索条件
|
||||
if (searchText.value) {
|
||||
where.keywords = searchText.value;
|
||||
}
|
||||
where.isStaff = true;
|
||||
where.idleOnly = idleOnly.value;
|
||||
return pageTowerEquipment({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: TowerEquipmentParam) => {
|
||||
tableRef?.value?.reload({ page: 1, where });
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: TowerEquipment) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
updateVisible(false);
|
||||
emit("done", record);
|
||||
}
|
||||
]);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({ page, limit, where, orders }) => {
|
||||
where = {};
|
||||
// 搜索条件
|
||||
if (searchText.value) {
|
||||
where.keywords = searchText.value;
|
||||
}
|
||||
where.isStaff = true;
|
||||
return pageTowerEquipment({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: TowerEquipmentParam) => {
|
||||
tableRef?.value?.reload({ page: 1, where });
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: TowerEquipment) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
updateVisible(false);
|
||||
emit('done', record);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
</script>
|
||||
<style lang="less"></style>
|
||||
|
||||
@@ -31,7 +31,7 @@ export const LAYOUT_PATH = '/';
|
||||
export const REDIRECT_PATH = '/redirect';
|
||||
// 开启页签栏是否缓存组件
|
||||
//export const TAB_KEEP_ALIVE = !import.meta.env.DEV;
|
||||
export const TAB_KEEP_ALIVE = true;
|
||||
export const TAB_KEEP_ALIVE = false;
|
||||
// token 传递的 header 名称
|
||||
export const TOKEN_HEADER_NAME = 'Authorization';
|
||||
// token 存储的名称
|
||||
|
||||
@@ -23,13 +23,13 @@
|
||||
<!-- >-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </div>-->
|
||||
<div class="ele-admin-header-tool-item" @click="myOrder"> 费用 </div>
|
||||
<!-- <div class="ele-admin-header-tool-item" @click="myOrder"> 费用 </div>-->
|
||||
<!-- 工单系统 -->
|
||||
<div class="ele-admin-header-tool-item">
|
||||
<a-dropdown placement="bottom" :overlay-style="{ minWidth: '100px' }">
|
||||
<div class="ele-admin-header-avatar">
|
||||
<span :class="{ 'hidden-sm-and-down': styleResponsive }"> 工单 </span>
|
||||
</div>
|
||||
<!-- <div class="ele-admin-header-avatar">-->
|
||||
<!-- <span :class="{ 'hidden-sm-and-down': styleResponsive }"> 工单 </span>-->
|
||||
<!-- </div>-->
|
||||
<template #overlay>
|
||||
<a-menu :selectable="false" @click="onUserDropClick">
|
||||
<a-menu-item key="taskAdd">
|
||||
@@ -143,7 +143,7 @@
|
||||
<div class="ele-cell" align="center">
|
||||
<div class="ele-cell-content">
|
||||
<logout-outlined />
|
||||
{{ t('layout.header.logout') }}
|
||||
退出登录
|
||||
</div>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
@@ -240,8 +240,8 @@
|
||||
} else if (key === 'logout') {
|
||||
// 退出登录
|
||||
Modal.confirm({
|
||||
title: t('layout.logout.title'),
|
||||
content: t('layout.logout.message'),
|
||||
title: '提示',
|
||||
content: '确认退出吗',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
<template>
|
||||
<div class="ele-text-center" style="padding: 16px 0">
|
||||
<div class="ele-text-secondary" style="margin-top: 8px">
|
||||
{{ t('layout.footer.copyright') }}
|
||||
<!-- {{ t('layout.footer.copyright') }}-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
// import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
// const { t } = useI18n();
|
||||
</script>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
console.log(aoa);
|
||||
aoa.slice(1).map((d) => {
|
||||
const array = ['闲置', '报废', '注销', '转卖'];
|
||||
const array = ['闲置', '报废', '注销', '转卖', '在用', '场地'];
|
||||
importData.value.push({
|
||||
status: array.indexOf(d[0]),
|
||||
name: d[1],
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<a-input-password
|
||||
size="large"
|
||||
v-model:value="form.password"
|
||||
:placeholder="t('login.password')"
|
||||
:placeholder="'请输入密码'"
|
||||
@pressEnter="submit"
|
||||
>
|
||||
<template #prefix>
|
||||
@@ -67,7 +67,7 @@
|
||||
type="text"
|
||||
:maxlength="5"
|
||||
v-model:value="form.code"
|
||||
:placeholder="t('login.code')"
|
||||
:placeholder="'请输入验证码'"
|
||||
@pressEnter="submit"
|
||||
>
|
||||
<template #prefix>
|
||||
@@ -81,7 +81,7 @@
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-checkbox v-model:checked="form.remember">
|
||||
{{ t('login.remember') }}
|
||||
记住密码
|
||||
</a-checkbox>
|
||||
<!-- <router-link-->
|
||||
<!-- to="/forget"-->
|
||||
@@ -99,7 +99,7 @@
|
||||
:loading="loading"
|
||||
@click="submit"
|
||||
>
|
||||
{{ loading ? t('login.loading') : t('login.login') }}
|
||||
{{ loading ? '登录中' : '登录' }}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</template>
|
||||
@@ -150,7 +150,7 @@
|
||||
WechatOutlined,
|
||||
WeiboOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
// import I18nIcon from '@/layout/components/i18n-icon.vue';
|
||||
import I18nIcon from '@/layout/components/i18n-icon.vue';
|
||||
// import { getToken } from '@/utils/token-util';
|
||||
// import { TENANT_ID } from '@/config/setting';
|
||||
import { goHomeRoute, cleanPageTabs } from '@/utils/page-tab-util';
|
||||
@@ -189,21 +189,21 @@
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: t('login.username'),
|
||||
message: '请输入用户名',
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: t('login.password'),
|
||||
message: '请输入密码',
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: t('login.code'),
|
||||
message: '请输入验证码',
|
||||
type: 'string'
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,192 +1,193 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-split-layout
|
||||
width="266px"
|
||||
allow-collapse
|
||||
:right-style="{ overflow: 'hidden' }"
|
||||
:style="{ minHeight: 'calc(100vh - 152px)' }"
|
||||
>
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="dictId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:current="current"
|
||||
selection-type="radio"
|
||||
:row-selection="{ columnWidth: 32 }"
|
||||
:need-page="false"
|
||||
:toolkit="[]"
|
||||
height="calc(100vh - 290px)"
|
||||
tools-theme="default"
|
||||
class="sys-dict-table"
|
||||
@done="done"
|
||||
>
|
||||
<template #toolbar>
|
||||
<a-space :size="10">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="openEdit()">
|
||||
<template #icon>
|
||||
<plus-outlined />
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-split-layout
|
||||
width="266px"
|
||||
allow-collapse
|
||||
:right-style="{ overflow: 'hidden' }"
|
||||
:style="{ minHeight: 'calc(100vh - 152px)' }"
|
||||
>
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="dictId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:current="current"
|
||||
selection-type="radio"
|
||||
:row-selection="{ columnWidth: 32 }"
|
||||
:need-page="false"
|
||||
:toolkit="[]"
|
||||
height="calc(100vh - 290px)"
|
||||
tools-theme="default"
|
||||
class="sys-dict-table"
|
||||
@done="done"
|
||||
>
|
||||
<template #toolbar>
|
||||
<a-space :size="10">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="openEdit()">
|
||||
<template #icon>
|
||||
<plus-outlined />
|
||||
</template>
|
||||
<span>新建</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
:disabled="!current"
|
||||
class="ele-btn-icon"
|
||||
@click="openEdit(current)"
|
||||
>
|
||||
<template #icon>
|
||||
<edit-outlined />
|
||||
</template>
|
||||
<span>修改</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
:disabled="!current"
|
||||
class="ele-btn-icon"
|
||||
@click="remove"
|
||||
>
|
||||
<template #icon>
|
||||
<delete-outlined />
|
||||
</template>
|
||||
<span>删除</span>
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'dictName'">
|
||||
<div>
|
||||
<span>{{ record.dictName }}</span>
|
||||
<span class="ele-text-placeholder">{{ record.dictCode }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
<template #content>
|
||||
<dict-data
|
||||
v-if="current && current.dictId"
|
||||
:dict-id="current.dictId"
|
||||
/>
|
||||
</template>
|
||||
<span>新建</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
:disabled="!current"
|
||||
class="ele-btn-icon"
|
||||
@click="openEdit(current)"
|
||||
>
|
||||
<template #icon>
|
||||
<edit-outlined />
|
||||
</template>
|
||||
<span>修改</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
:disabled="!current"
|
||||
class="ele-btn-icon"
|
||||
@click="remove"
|
||||
>
|
||||
<template #icon>
|
||||
<delete-outlined />
|
||||
</template>
|
||||
<span>删除</span>
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'dictName'">
|
||||
{{ record.dictName }}
|
||||
<span class="ele-text-placeholder">
|
||||
{{ record.dictCode }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
<template #content>
|
||||
<dict-data
|
||||
v-if="current && current.dictId"
|
||||
:dict-id="current.dictId"
|
||||
/>
|
||||
</template>
|
||||
</ele-split-layout>
|
||||
</a-card>
|
||||
<!-- 编辑弹窗 -->
|
||||
<dict-edit v-model:visible="showEdit" :data="editData" @done="reload" />
|
||||
</div>
|
||||
</ele-split-layout>
|
||||
</a-card>
|
||||
<!-- 编辑弹窗 -->
|
||||
<dict-edit v-model:visible="showEdit" :data="editData" @done="reload" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { createVNode, ref } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import {
|
||||
import { createVNode, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import {
|
||||
PlusOutlined,
|
||||
EditOutlined,
|
||||
DeleteOutlined,
|
||||
ExclamationCircleOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import type { EleProTable } from 'ele-admin-pro';
|
||||
import type {
|
||||
} from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem,
|
||||
EleProTableDone
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import DictData from './components/dict-data.vue';
|
||||
import DictEdit from './components/dict-edit.vue';
|
||||
import { listDictionaries, removeDict } from '@/api/system/dict';
|
||||
import type { Dict } from '@/api/system/dict/model';
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import DictData from "./components/dict-data.vue";
|
||||
import DictEdit from "./components/dict-edit.vue";
|
||||
import { listDictionaries, removeDict } from "@/api/system/dict";
|
||||
import type { Dict } from "@/api/system/dict/model";
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: 'index',
|
||||
width: 35,
|
||||
ellipsis: true,
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
key: "index",
|
||||
width: 35,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: '字典名称',
|
||||
dataIndex: 'dictName',
|
||||
key: 'dictName'
|
||||
title: "字典名称",
|
||||
dataIndex: "dictName",
|
||||
key: "dictName"
|
||||
}
|
||||
]);
|
||||
]);
|
||||
|
||||
// 表格选中数据
|
||||
const current = ref<Dict | null>(null);
|
||||
// 表格选中数据
|
||||
const current = ref<Dict | null>(null);
|
||||
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
|
||||
// 编辑回显数据
|
||||
const editData = ref<Dict | null>(null);
|
||||
// 编辑回显数据
|
||||
const editData = ref<Dict | null>(null);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = () => {
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = () => {
|
||||
return listDictionaries();
|
||||
};
|
||||
};
|
||||
|
||||
/* 表格渲染完成回调 */
|
||||
const done: EleProTableDone<Dict> = (res) => {
|
||||
/* 表格渲染完成回调 */
|
||||
const done: EleProTableDone<Dict> = (res) => {
|
||||
if (res.data?.length) {
|
||||
current.value = res.data[0];
|
||||
current.value = res.data[0];
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* 刷新表格 */
|
||||
const reload = () => {
|
||||
/* 刷新表格 */
|
||||
const reload = () => {
|
||||
tableRef?.value?.reload();
|
||||
};
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Dict | null) => {
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Dict | null) => {
|
||||
editData.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
};
|
||||
|
||||
/* 删除 */
|
||||
const remove = () => {
|
||||
/* 删除 */
|
||||
const remove = () => {
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要删除选中的字典吗?',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
removeDict(current.value?.dictId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
title: "提示",
|
||||
content: "确定要删除选中的字典吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeDict(current.value?.dictId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'SystemDict'
|
||||
};
|
||||
export default {
|
||||
name: "SystemDict"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sys-dict-table :deep(.ant-table-body) {
|
||||
.sys-dict-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
.dict-code {
|
||||
}
|
||||
|
||||
.dict-code {
|
||||
color: #cccccc;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<!-- 机构编辑弹窗 -->
|
||||
<!-- 部门编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="620"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:title="isUpdate ? '修改机构' : '添加机构'"
|
||||
:title="isUpdate ? '修改部门' : '添加部门'"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
@ok="save"
|
||||
@@ -20,53 +20,28 @@
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 12 }"
|
||||
>
|
||||
<a-form-item label="上级机构" name="parentId">
|
||||
<a-form-item label="上级部门" name="parentId">
|
||||
<org-select
|
||||
:data="organizationList"
|
||||
placeholder="请选择上级机构"
|
||||
placeholder="请选择上级部门"
|
||||
v-model:value="form.parentId"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="机构名称" name="organizationName">
|
||||
<a-form-item label="部门名称" name="organizationName">
|
||||
<a-input
|
||||
allow-clear
|
||||
:maxlength="20"
|
||||
placeholder="请输入机构名称"
|
||||
placeholder="请输入部门名称"
|
||||
v-model:value="form.organizationName"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="机构全称" name="organizationFullName">
|
||||
<a-input
|
||||
allow-clear
|
||||
:maxlength="100"
|
||||
placeholder="请输入机构全称"
|
||||
v-model:value="form.organizationFullName"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="机构代码">
|
||||
<a-input
|
||||
allow-clear
|
||||
:maxlength="20"
|
||||
placeholder="请输入机构代码"
|
||||
v-model:value="form.organizationCode"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 12 }"
|
||||
>
|
||||
<a-form-item label="机构类型" name="organizationType">
|
||||
<a-form-item label="部门类型" name="organizationType">
|
||||
<org-type-select v-model:value="form.organizationType" />
|
||||
</a-form-item>
|
||||
<a-form-item label="排序号" name="sortNumber">
|
||||
<a-input-number
|
||||
:min="0"
|
||||
:max="99999"
|
||||
class="ele-fluid"
|
||||
placeholder="请输入排序号"
|
||||
v-model:value="form.sortNumber"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="备注">
|
||||
<a-textarea
|
||||
:rows="4"
|
||||
@@ -110,9 +85,9 @@
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Organization | null;
|
||||
// 机构id
|
||||
// 部门id
|
||||
organizationId?: number;
|
||||
// 全部机构
|
||||
// 全部部门
|
||||
organizationList: Organization[];
|
||||
}>();
|
||||
|
||||
@@ -142,15 +117,7 @@
|
||||
organizationName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入机构名称',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
organizationFullName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入机构全称',
|
||||
message: '请输入部门名称',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
@@ -158,19 +125,11 @@
|
||||
organizationType: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择机构类型',
|
||||
message: '请选择部门类型',
|
||||
type: 'string',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
sortNumber: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入排序号',
|
||||
type: 'number',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
/* 保存编辑 */
|
||||
|
||||
@@ -53,13 +53,21 @@
|
||||
v-model:value="form.realName"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="所属机构" name="type">
|
||||
<a-form-item label="所属部门" name="type">
|
||||
<org-select
|
||||
:data="organizationList"
|
||||
placeholder="请选择所属机构"
|
||||
placeholder="请选择所属部门"
|
||||
v-model:value="form.organizationId"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="小程序权限" name="type">
|
||||
<a-select placeholder="必选项" style="width: 250px" size="small"
|
||||
v-model:value="form.userLevel">
|
||||
<a-select-option v-for="(item, index) in USER_LEVEL_LIST" :key="index" :value="index">
|
||||
{{ item }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 12 }"
|
||||
@@ -124,6 +132,7 @@
|
||||
import OrgSelect from './org-select.vue';
|
||||
// import { getDictionaryOptions } from '@/utils/common';
|
||||
import { Organization } from '@/api/system/organization/model';
|
||||
import { USER_LEVEL_LIST } from "@/api/system/user/model";
|
||||
|
||||
// 是否开启响应式布局
|
||||
const themeStore = useThemeStore();
|
||||
@@ -153,6 +162,7 @@
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
|
||||
|
||||
// 表单数据
|
||||
const { form, resetFields, assignFields } = useFormData<User>({
|
||||
type: undefined,
|
||||
@@ -168,6 +178,7 @@
|
||||
password: '',
|
||||
introduction: '',
|
||||
organizationId: undefined,
|
||||
userLevel: undefined,
|
||||
birthday: '',
|
||||
idCard: '',
|
||||
comments: ''
|
||||
|
||||
@@ -103,6 +103,11 @@
|
||||
¥{{ formatNumber(record.expendMoney) }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'userLevel'">
|
||||
<span>
|
||||
{{ USER_LEVEL_LIST[record.userLevel] }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'status'">
|
||||
<a-switch
|
||||
:checked="record.status === 0"
|
||||
@@ -175,6 +180,7 @@
|
||||
import { getDictionaryOptions } from '@/utils/common';
|
||||
import { listOrganizations } from '@/api/system/organization';
|
||||
import { Organization } from '@/api/system/organization/model';
|
||||
import { USER_LEVEL_LIST } from "@/api/system/user/model";
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(true);
|
||||
@@ -256,13 +262,6 @@
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
// {
|
||||
// title: '操作',
|
||||
// key: 'action',
|
||||
// width: 200,
|
||||
// fixed: 'left',
|
||||
// align: 'center'
|
||||
// },
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'userId',
|
||||
@@ -314,86 +313,6 @@
|
||||
hideInTable: true,
|
||||
showSorterTooltip: false
|
||||
},
|
||||
{
|
||||
title: '可用余额',
|
||||
dataIndex: 'balance',
|
||||
key: 'balance',
|
||||
sorter: true,
|
||||
showSorterTooltip: false
|
||||
},
|
||||
{
|
||||
title: '实际消费金额',
|
||||
dataIndex: 'expendMoney',
|
||||
key: 'expendMoney',
|
||||
sorter: true,
|
||||
showSorterTooltip: false
|
||||
},
|
||||
{
|
||||
title: '可用积分',
|
||||
dataIndex: 'points',
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
title: '注册来源',
|
||||
key: 'platform',
|
||||
dataIndex: 'platform',
|
||||
sorter: true,
|
||||
hideInTable: true,
|
||||
customRender: ({ text }) => ['未知', '网站', '小程序', 'APP'][text]
|
||||
},
|
||||
{
|
||||
title: '证件号码',
|
||||
dataIndex: 'idCard',
|
||||
hideInTable: true
|
||||
},
|
||||
{
|
||||
title: '出生日期',
|
||||
dataIndex: 'birthday',
|
||||
key: 'birthday',
|
||||
hideInTable: true
|
||||
},
|
||||
{
|
||||
title: '省份',
|
||||
dataIndex: 'province',
|
||||
key: 'province',
|
||||
hideInTable: true
|
||||
},
|
||||
{
|
||||
title: '城市',
|
||||
dataIndex: 'city',
|
||||
key: 'city',
|
||||
hideInTable: true,
|
||||
showSorterTooltip: false
|
||||
},
|
||||
{
|
||||
title: '地区',
|
||||
dataIndex: 'region',
|
||||
key: 'region',
|
||||
hideInTable: true,
|
||||
showSorterTooltip: false
|
||||
},
|
||||
{
|
||||
title: '个人简介',
|
||||
dataIndex: 'introduction',
|
||||
key: 'introduction',
|
||||
hideInTable: true,
|
||||
showSorterTooltip: false
|
||||
},
|
||||
{
|
||||
title: '邮箱认证',
|
||||
dataIndex: 'emailVerified',
|
||||
sorter: true,
|
||||
hideInTable: true,
|
||||
showSorterTooltip: false,
|
||||
customRender: ({ text }) => ['未认证', '已认证'][text]
|
||||
},
|
||||
{
|
||||
title: '实名认证',
|
||||
dataIndex: 'certification',
|
||||
sorter: true,
|
||||
hideInTable: true,
|
||||
customRender: ({ text }) => ['未认证', '已认证'][text]
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
dataIndex: 'roles',
|
||||
@@ -403,6 +322,12 @@
|
||||
filterMultiple: false,
|
||||
filters: roles.value
|
||||
},
|
||||
{
|
||||
title: '小程序权限',
|
||||
dataIndex: 'userLevel',
|
||||
key: 'userLevel',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
@@ -419,7 +344,14 @@
|
||||
showSorterTooltip: false,
|
||||
width: 90,
|
||||
align: 'center'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
fixed: 'left',
|
||||
align: 'center'
|
||||
},
|
||||
]);
|
||||
|
||||
// 默认搜索条件
|
||||
|
||||
@@ -1,211 +1,219 @@
|
||||
<!-- 编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="75%"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
:maxable="maxable"
|
||||
:title="isUpdate ? '编辑配件' : '添加配件'"
|
||||
:body-style="{ paddingBottom: '28px' }"
|
||||
@update:visible="updateVisible"
|
||||
@ok="save"
|
||||
>
|
||||
<div style="background-color: #f3f3f3; padding: 8px">
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
:label-col="{ md: { span: 7 }, sm: { span: 4 }, xs: { span: 24 } }"
|
||||
:wrapper-col="{ md: { span: 17 }, sm: { span: 20 }, xs: { span: 24 } }"
|
||||
>
|
||||
<a-card title="基本信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
<ele-modal
|
||||
width="75%"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
:maxable="maxable"
|
||||
:title="isUpdate ? '编辑配件' : '添加配件'"
|
||||
:body-style="{ paddingBottom: '28px' }"
|
||||
@update:visible="updateVisible"
|
||||
@ok="save"
|
||||
>
|
||||
<div style="background-color: #f3f3f3; padding: 8px">
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
:label-col="{ md: { span: 7 }, sm: { span: 4 }, xs: { span: 24 } }"
|
||||
:wrapper-col="{ md: { span: 17 }, sm: { span: 20 }, xs: { span: 24 } }"
|
||||
>
|
||||
<a-form-item label="配件分类" name="accessoryCategory">
|
||||
<AccessoryCategory
|
||||
v-model:value="form.accessoryCategory"
|
||||
valueField="label"
|
||||
placeholder="请选择配件分类"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="配件规格" name="accessorySpecs">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入配件规格"
|
||||
v-model:value="form.accessorySpecs"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="重量" name="accessoryWeight">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入配件规格"
|
||||
v-model:value="form.accessoryWeight"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="配件名称" name="accessoryName">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入配件名称"
|
||||
v-model:value="form.accessoryName"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="单位" name="accessoryUnit">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入配件单位"
|
||||
v-model:value="form.accessoryUnit"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="单价" name="accessoryPrice">
|
||||
<a-input-number
|
||||
allow-clear
|
||||
:min="0"
|
||||
:precision="2"
|
||||
style="width: 200px"
|
||||
placeholder="请输入配件单价"
|
||||
v-model:value="form.accessoryPrice"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="设备型号" name="accessoryModel">
|
||||
<TowerSelectModel
|
||||
:placeholder="`请选择设备型号`"
|
||||
v-model:value="form.accessoryModel"
|
||||
@done="chooseAccessoryModel"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="使用年限" name="lifeYear">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入使用年限"
|
||||
v-model:value="form.lifeYear"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-divider style="height: 8px" />
|
||||
<a-card title="出厂信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="配件编号" name="accessoryNo">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入当前位置"
|
||||
v-model:value="form.accessoryNo"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="产权单位" name="companyName">
|
||||
<DictSelect
|
||||
:placeholder="'请选择产权单位'"
|
||||
v-model:value="form.companyName"
|
||||
:dict-code="'PropertyCompany'"
|
||||
@done="chooseCompanyName"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="备注" name="comments">
|
||||
<a-textarea
|
||||
:rows="4"
|
||||
:maxlength="200"
|
||||
placeholder="请输入备注"
|
||||
v-model:value="form.comments"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="制造厂商" name="manufactor">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入制造厂商"
|
||||
v-model:value="form.manufactor"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="厂商编号" name="manufactorNo">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入厂商编号"
|
||||
v-model:value="form.manufactorNo"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="出厂日期" name="factoryDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择日期"
|
||||
v-model:value="form.factoryDate"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="报废日期" name="scrapDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择日期"
|
||||
v-model:value="form.scrapDate"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-divider style="height: 8px" />
|
||||
<a-card title="多选适配设备型号" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="设备型号" name="accessoryModelMultiple">
|
||||
<TowerSelectModelMultiple
|
||||
:placeholder="`请选择设备型号`"
|
||||
v-model:value="form.accessoryModelMultiple"
|
||||
@done="chooseMultiple"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-form>
|
||||
</div>
|
||||
</ele-modal>
|
||||
<a-card title="基本信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="配件分类" name="accessoryCategory">
|
||||
<AccessoryCategory
|
||||
v-model:value="form.accessoryCategory"
|
||||
valueField="label"
|
||||
placeholder="请选择配件分类"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="配件规格" name="accessorySpecs">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入配件规格"
|
||||
v-model:value="form.accessorySpecs"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="重量" name="accessoryWeight">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入配件规格"
|
||||
v-model:value="form.accessoryWeight"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="购买数量">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入购买数量"
|
||||
v-model:value="form.accessoryNum"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="生成厂家" name="accessoryName">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入生成厂家"
|
||||
v-model:value="form.accessoryName"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="单位" name="accessoryUnit">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入配件单位"
|
||||
v-model:value="form.accessoryUnit"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="单价" name="accessoryPrice">
|
||||
<a-input-number
|
||||
allow-clear
|
||||
:min="0"
|
||||
:precision="2"
|
||||
style="width: 200px"
|
||||
placeholder="请输入配件单价"
|
||||
v-model:value="form.accessoryPrice"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="设备型号" name="accessoryModel">
|
||||
<TowerSelectModel
|
||||
:placeholder="`请选择设备型号`"
|
||||
v-model:value="form.accessoryModel"
|
||||
@done="chooseAccessoryModel"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="使用年限" name="lifeYear">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入使用年限"
|
||||
v-model:value="form.lifeYear"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="购买日期" name="lifeYear">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择日期"
|
||||
v-model:value="form.buyDate"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-divider style="height: 8px" />
|
||||
<a-card title="出厂信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="配件编号" name="accessoryNo">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入当前位置"
|
||||
v-model:value="form.accessoryNo"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="产权单位" name="companyName">
|
||||
<DictSelect
|
||||
:placeholder="'请选择产权单位'"
|
||||
v-model:value="form.companyName"
|
||||
:dict-code="'PropertyCompany'"
|
||||
@done="chooseCompanyName"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="制造厂商" name="manufactor">
|
||||
<a-input
|
||||
allow-clear
|
||||
placeholder="请输入制造厂商"
|
||||
v-model:value="form.manufactor"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="报废日期" name="scrapDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择日期"
|
||||
v-model:value="form.scrapDate"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="出厂日期" name="factoryDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择日期"
|
||||
v-model:value="form.factoryDate"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="备注" name="comments">
|
||||
<a-textarea
|
||||
:rows="4"
|
||||
:maxlength="200"
|
||||
placeholder="请输入备注"
|
||||
v-model:value="form.comments"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-divider style="height: 8px" />
|
||||
<a-card title="多选适配设备型号" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 8, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="设备型号" name="accessoryModelMultiple">
|
||||
<TowerSelectModelMultiple
|
||||
:placeholder="`请选择设备型号`"
|
||||
v-model:value="form.accessoryModelMultiple"
|
||||
@done="chooseMultiple"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-form>
|
||||
</div>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Form, message } from 'ant-design-vue';
|
||||
import { assignObject } from 'ele-admin-pro';
|
||||
import { addAccessory, updateAccessory } from '@/api/tower/accessory';
|
||||
import { Accessory } from '@/api/tower/accessory/model';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { FormInstance } from 'ant-design-vue/es/form';
|
||||
import { Customer } from '@/api/oa/customer/model';
|
||||
import { Category } from '@/api/goods/category/model';
|
||||
import { TowerModel } from '@/api/tower/model/model';
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { Form, message } from "ant-design-vue";
|
||||
import { assignObject } from "ele-admin-pro";
|
||||
import { addAccessory, updateAccessory } from "@/api/tower/accessory";
|
||||
import { Accessory } from "@/api/tower/accessory/model";
|
||||
import { useThemeStore } from "@/store/modules/theme";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { FormInstance } from "ant-design-vue/es/form";
|
||||
import { Customer } from "@/api/oa/customer/model";
|
||||
import { Category } from "@/api/goods/category/model";
|
||||
import { TowerModel } from "@/api/tower/model/model";
|
||||
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
const useForm = Form.useForm;
|
||||
// 是否开启响应式布局
|
||||
const themeStore = useThemeStore();
|
||||
const { styleResponsive } = storeToRefs(themeStore);
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
const useForm = Form.useForm;
|
||||
// 是否开启响应式布局
|
||||
const themeStore = useThemeStore();
|
||||
const { styleResponsive } = storeToRefs(themeStore);
|
||||
|
||||
const props = defineProps<{
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
@@ -213,186 +221,183 @@
|
||||
categoryList?: Category[];
|
||||
modelTree?: TowerModel[];
|
||||
modelList?: TowerModel[];
|
||||
}>();
|
||||
}>();
|
||||
|
||||
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 formRef = ref<FormInstance | null>(null);
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
// 是否显示最大化切换按钮
|
||||
const maxable = ref(true);
|
||||
// 表格选中数据
|
||||
const formRef = ref<FormInstance | null>(null);
|
||||
|
||||
// 用户信息
|
||||
const form = reactive<Accessory>({
|
||||
// 用户信息
|
||||
const form = reactive<Accessory>({
|
||||
accessoryId: undefined,
|
||||
accessoryName: '',
|
||||
accessoryNo: '',
|
||||
accessoryName: "",
|
||||
accessoryNo: "",
|
||||
accessoryCategory: undefined,
|
||||
accessoryModel: '',
|
||||
accessoryModel: "",
|
||||
accessoryModelMultiple: [],
|
||||
accessorySpecs: '',
|
||||
accessorySpecs: "",
|
||||
accessoryPrice: 0,
|
||||
accessoryUnit: '',
|
||||
accessoryStock: '',
|
||||
companyName: '',
|
||||
manufactor: '',
|
||||
accessoryWeight: '',
|
||||
manufactorNo: '',
|
||||
accessoryUnit: "",
|
||||
accessoryNum: 0,
|
||||
accessoryStock: "",
|
||||
companyName: "",
|
||||
manufactor: "",
|
||||
accessoryWeight: "",
|
||||
manufactorNo: "",
|
||||
lifeYear: undefined,
|
||||
factoryDate: '',
|
||||
scrapDate: '',
|
||||
factoryDate: "",
|
||||
scrapDate: "",
|
||||
status: undefined,
|
||||
comments: '',
|
||||
comments: "",
|
||||
sortNumber: undefined,
|
||||
userId: undefined,
|
||||
createTime: '',
|
||||
updateTime: ''
|
||||
});
|
||||
createTime: "",
|
||||
updateTime: "",
|
||||
buyDate: ""
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
accessoryCategory: [
|
||||
{
|
||||
required: true,
|
||||
type: 'array',
|
||||
message: '请输入配件分类',
|
||||
trigger: 'blur'
|
||||
}
|
||||
{
|
||||
required: true,
|
||||
type: "array",
|
||||
message: "请输入配件分类",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
accessoryName: [
|
||||
{
|
||||
required: true,
|
||||
type: 'string',
|
||||
message: '请输入配件名称',
|
||||
trigger: 'blur'
|
||||
}
|
||||
{
|
||||
required: true,
|
||||
type: "string",
|
||||
message: "请输入生成厂家",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
accessoryModel: [
|
||||
{
|
||||
required: true,
|
||||
type: 'string',
|
||||
message: '请输入设备型号',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
accessoryWeight: [
|
||||
{
|
||||
required: true,
|
||||
type: 'string',
|
||||
message: '请输入设备重量',
|
||||
trigger: 'blur'
|
||||
}
|
||||
{
|
||||
required: true,
|
||||
type: "string",
|
||||
message: "请输入设备型号",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
accessorySpecs: [
|
||||
{
|
||||
required: true,
|
||||
type: 'string',
|
||||
message: '请输入设备规格',
|
||||
trigger: 'blur'
|
||||
}
|
||||
{
|
||||
required: true,
|
||||
type: "string",
|
||||
message: "请输入设备规格",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
accessoryUnit: [
|
||||
{
|
||||
required: true,
|
||||
type: 'string',
|
||||
message: '请输入单位',
|
||||
trigger: 'blur'
|
||||
}
|
||||
{
|
||||
required: true,
|
||||
type: "string",
|
||||
message: "请输入单位",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
const { resetFields } = useForm(form, rules);
|
||||
const chooseCompanyName = (data: Customer) => {
|
||||
const { resetFields } = useForm(form, rules);
|
||||
const chooseCompanyName = (data: Customer) => {
|
||||
form.companyName = data.customerName;
|
||||
};
|
||||
const chooseAccessoryModel = (data: TowerModel) => {
|
||||
};
|
||||
const chooseAccessoryModel = (data: TowerModel) => {
|
||||
form.accessoryModel = data.name?.concat(String(data.model));
|
||||
form.lifeYear = data.yearLife;
|
||||
};
|
||||
const chooseMultiple = (data) => {
|
||||
};
|
||||
const chooseMultiple = (data) => {
|
||||
form.accessoryModelMultiple = [];
|
||||
data.map((d) => {
|
||||
form.accessoryModelMultiple?.push(`${d.name}${d.model}`);
|
||||
form.accessoryModelMultiple?.push(`${d.name}${d.model}`);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
if (!formRef.value) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
loading.value = true;
|
||||
console.log(form.accessoryCategory?.[0]);
|
||||
const formData = {
|
||||
...form,
|
||||
accessoryCategory: `${form.accessoryCategory?.[0]} / ${form.accessoryCategory?.[1]}`,
|
||||
accessoryModelMultiple: JSON.stringify(form.accessoryModelMultiple)
|
||||
};
|
||||
const saveOrUpdate = isUpdate.value ? updateAccessory : addAccessory;
|
||||
saveOrUpdate(formData)
|
||||
.then((msg) => {
|
||||
loading.value = false;
|
||||
message.success(msg);
|
||||
updateVisible(false);
|
||||
emit('done');
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
.validate()
|
||||
.then(() => {
|
||||
loading.value = true;
|
||||
console.log(form.accessoryCategory?.[0]);
|
||||
const formData = {
|
||||
...form,
|
||||
accessoryCategory: `${form.accessoryCategory?.[0]} / ${form.accessoryCategory?.[1]}`,
|
||||
accessoryModelMultiple: JSON.stringify(form.accessoryModelMultiple)
|
||||
};
|
||||
const saveOrUpdate = isUpdate.value ? updateAccessory : addAccessory;
|
||||
saveOrUpdate(formData)
|
||||
.then((msg) => {
|
||||
loading.value = false;
|
||||
message.success(msg);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
assignObject(form, props.data);
|
||||
const accessoryCategory = String(props.data.accessoryCategory);
|
||||
const split = accessoryCategory?.split(' / ');
|
||||
if (typeof split == 'object') {
|
||||
form.accessoryCategory = split;
|
||||
}
|
||||
if (props.data.accessoryModelMultiple) {
|
||||
form.accessoryModelMultiple = JSON.parse(
|
||||
String(form.accessoryModelMultiple)
|
||||
);
|
||||
}
|
||||
isUpdate.value = true;
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
assignObject(form, props.data);
|
||||
const accessoryCategory = String(props.data.accessoryCategory);
|
||||
const split = accessoryCategory?.split(" / ");
|
||||
if (typeof split == "object") {
|
||||
form.accessoryCategory = split;
|
||||
}
|
||||
if (props.data.accessoryModelMultiple) {
|
||||
form.accessoryModelMultiple = JSON.parse(
|
||||
String(form.accessoryModelMultiple)
|
||||
);
|
||||
}
|
||||
isUpdate.value = true;
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
resetFields();
|
||||
}
|
||||
} else {
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
</script>
|
||||
<style lang="less"></style>
|
||||
|
||||
<style lang="less">
|
||||
.tab-pane {
|
||||
.tab-pane {
|
||||
min-height: 300px;
|
||||
}
|
||||
.ml-10 {
|
||||
}
|
||||
|
||||
.ml-10 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.upload-text {
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
margin-right: 70px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,406 +1,406 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="accessoryId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
:customRow="customRow"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 3000 }"
|
||||
class="sys-org-table"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@batchMove="openMove"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'accessoryName'">
|
||||
<a-avatar
|
||||
:size="30"
|
||||
:src="`${record.accessoryAvatar}`"
|
||||
style="margin-right: 4px"
|
||||
:srcset="`https://file.wsdns.cn/${record.accessoryAvatar}`"
|
||||
>
|
||||
<template #icon>
|
||||
<UserOutlined />
|
||||
</template>
|
||||
</a-avatar>
|
||||
<a-tooltip title="查看详情">
|
||||
<a href="#" @click="openInfo(record)">{{
|
||||
record.accessoryName
|
||||
}}</a>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'progress'">
|
||||
<div v-for="(d, i) in progressDict" :key="i">
|
||||
<span v-if="d.value === record.progress">{{ d.label }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'accessoryType'">
|
||||
<div v-for="(d, i) in JSON.parse(accessoryType)" :key="i">
|
||||
<span v-if="d.value === record.accessoryType">{{
|
||||
d.value
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag v-if="record.status === 0" color="green">正常</a-tag>
|
||||
<a-tag v-if="record.status === 1" color="red">待审核</a-tag>
|
||||
<a-tag v-if="record.status === 2" color="purple">已驳回</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'nickname'">
|
||||
<a-tooltip :title="`${record.nickname}`">
|
||||
<a-avatar :src="record.userAvatar" size="small" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
<a-tooltip :title="`${toDateString(record.createTime)}`">
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a>库存分布</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="确定要删除此记录吗?"
|
||||
@confirm="remove(record)"
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="accessoryId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
:customRow="customRow"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 3000 }"
|
||||
class="sys-org-table"
|
||||
>
|
||||
<a class="ele-text-danger">删除</a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@batchMove="openMove"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'accessoryName'">
|
||||
<a-avatar
|
||||
:size="30"
|
||||
:src="`${record.accessoryAvatar}`"
|
||||
style="margin-right: 4px"
|
||||
:srcset="`https://file.wsdns.cn/${record.accessoryAvatar}`"
|
||||
>
|
||||
<template #icon>
|
||||
<UserOutlined />
|
||||
</template>
|
||||
</a-avatar>
|
||||
<a-tooltip title="查看详情">
|
||||
<a href="#" @click="openInfo(record)">{{
|
||||
record.accessoryName
|
||||
}}</a>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'progress'">
|
||||
<div v-for="(d, i) in progressDict" :key="i">
|
||||
<span v-if="d.value === record.progress">{{ d.label }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'accessoryType'">
|
||||
<div v-for="(d, i) in JSON.parse(accessoryType)" :key="i">
|
||||
<span v-if="d.value === record.accessoryType">{{
|
||||
d.value
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag v-if="record.status === 0" color="green">正常</a-tag>
|
||||
<a-tag v-if="record.status === 1" color="red">待审核</a-tag>
|
||||
<a-tag v-if="record.status === 2" color="purple">已驳回</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'nickname'">
|
||||
<a-tooltip :title="`${record.nickname}`">
|
||||
<a-avatar :src="record.userAvatar" size="small" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
<a-tooltip :title="`${toDateString(record.createTime)}`">
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<!-- <a-divider type="vertical" />-->
|
||||
<!-- <a>库存分布</a>-->
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="确定要删除此记录吗?"
|
||||
@confirm="remove(record)"
|
||||
>
|
||||
<a class="ele-text-danger">删除</a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<AccessoryEdit
|
||||
v-model:visible="showEdit"
|
||||
:data="current"
|
||||
:category-list="data"
|
||||
:model-tree="data2"
|
||||
:model-list="data2List"
|
||||
@done="reload"
|
||||
/>
|
||||
<!-- 批量转移弹窗 -->
|
||||
<!-- <AccessoryMove v-model:visible="showMove" :data="selection" @done="batchMove" />-->
|
||||
<!-- 编辑弹窗 -->
|
||||
<AccessoryEdit
|
||||
v-model:visible="showEdit"
|
||||
:data="current"
|
||||
:category-list="data"
|
||||
:model-tree="data2"
|
||||
:model-list="data2List"
|
||||
@done="reload"
|
||||
/>
|
||||
<!-- 批量转移弹窗 -->
|
||||
<!-- <AccessoryMove v-model:visible="showMove" :data="selection" @done="batchMove" />-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, createVNode, ref } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import {
|
||||
import { computed, createVNode, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import {
|
||||
ExclamationCircleOutlined,
|
||||
UserOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import type { EleProTable } from 'ele-admin-pro';
|
||||
import type {
|
||||
} from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { toDateString, toTreeData } from 'ele-admin-pro';
|
||||
import Search from './components/search.vue';
|
||||
import AccessoryEdit from './components/accessory-edit.vue';
|
||||
import {
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { toDateString, toTreeData } from "ele-admin-pro";
|
||||
import Search from "./components/search.vue";
|
||||
import AccessoryEdit from "./components/accessory-edit.vue";
|
||||
import {
|
||||
pageAccessory,
|
||||
removeAccessory,
|
||||
removeBatchAccessory
|
||||
} from '@/api/tower/accessory';
|
||||
import { timeAgo } from 'ele-admin-pro';
|
||||
import type { Accessory, AccessoryParam } from '@/api/tower/accessory/model';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { Category } from '@/api/goods/category/model';
|
||||
import { listCategory } from '@/api/goods/category';
|
||||
import { listTowerModel } from '@/api/tower/model';
|
||||
import { TowerModel } from '@/api/tower/model/model';
|
||||
} from "@/api/tower/accessory";
|
||||
import { timeAgo } from "ele-admin-pro";
|
||||
import type { Accessory, AccessoryParam } from "@/api/tower/accessory/model";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { Category } from "@/api/goods/category/model";
|
||||
import { listCategory } from "@/api/goods/category";
|
||||
import { listTowerModel } from "@/api/tower/model";
|
||||
import { TowerModel } from "@/api/tower/model/model";
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
const accessoryType = localStorage.getItem('accessoryType');
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
const accessoryType = localStorage.getItem("accessoryType");
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<Accessory[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<Accessory | null>(null);
|
||||
// 树形数据
|
||||
const data = ref<Category[]>([]);
|
||||
const data2 = ref<TowerModel[]>([]);
|
||||
const data2List = ref<TowerModel[]>([]);
|
||||
// 表格选中数据
|
||||
const selection = ref<Accessory[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<Accessory | null>(null);
|
||||
// 树形数据
|
||||
const data = ref<Category[]>([]);
|
||||
const data2 = ref<TowerModel[]>([]);
|
||||
const data2List = ref<TowerModel[]>([]);
|
||||
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 是否显示批量移动弹窗
|
||||
const showMove = ref(false);
|
||||
// 加载状态
|
||||
const loading = ref(true);
|
||||
// 树展开的key
|
||||
const expandedRowKeys = ref<number[]>([]);
|
||||
// 树选中的key
|
||||
const selectedRowKeys = ref<number[]>([]);
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 是否显示批量移动弹窗
|
||||
const showMove = ref(false);
|
||||
// 加载状态
|
||||
const loading = ref(true);
|
||||
// 树展开的key
|
||||
const expandedRowKeys = ref<number[]>([]);
|
||||
// 树选中的key
|
||||
const selectedRowKeys = ref<number[]>([]);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
if (filters) {
|
||||
where.progress = filters.progress;
|
||||
where.accessorySource = filters.accessorySource;
|
||||
where.accessoryType = filters.accessoryType;
|
||||
where.status = filters.status;
|
||||
where.progress = filters.progress;
|
||||
where.accessorySource = filters.accessorySource;
|
||||
where.accessoryType = filters.accessoryType;
|
||||
where.status = filters.status;
|
||||
}
|
||||
return pageAccessory({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: 'index',
|
||||
width: 48,
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: '配件编号',
|
||||
dataIndex: 'accessoryNo'
|
||||
title: "配件编号",
|
||||
dataIndex: "accessoryNo"
|
||||
},
|
||||
{
|
||||
title: '配件名称',
|
||||
dataIndex: 'accessoryName'
|
||||
title: "生成厂家",
|
||||
dataIndex: "accessoryName"
|
||||
},
|
||||
{
|
||||
title: '配件分类',
|
||||
dataIndex: 'accessoryCategory'
|
||||
title: "配件分类",
|
||||
dataIndex: "accessoryCategory"
|
||||
},
|
||||
{
|
||||
title: '适用设备型号',
|
||||
dataIndex: 'accessoryModel'
|
||||
title: "适用设备型号",
|
||||
dataIndex: "accessoryModel"
|
||||
},
|
||||
{
|
||||
title: '配件规格',
|
||||
dataIndex: 'accessorySpecs'
|
||||
title: "配件规格",
|
||||
dataIndex: "accessorySpecs"
|
||||
},
|
||||
{
|
||||
title: '单价',
|
||||
dataIndex: 'accessoryPrice'
|
||||
title: "单价",
|
||||
dataIndex: "accessoryPrice"
|
||||
},
|
||||
{
|
||||
title: '配件单位',
|
||||
dataIndex: 'accessoryUnit'
|
||||
title: "购买数量",
|
||||
dataIndex: "accessoryNum"
|
||||
},
|
||||
{
|
||||
title: '库存总量',
|
||||
dataIndex: 'accessoryStock'
|
||||
title: "配件单位",
|
||||
dataIndex: "accessoryUnit"
|
||||
},
|
||||
{
|
||||
title: '产权单位名称',
|
||||
dataIndex: 'companyName'
|
||||
title: "产权单位名称",
|
||||
dataIndex: "companyName"
|
||||
},
|
||||
{
|
||||
title: '制造厂商',
|
||||
dataIndex: 'manufactor'
|
||||
title: "制造厂商",
|
||||
dataIndex: "manufactor"
|
||||
},
|
||||
{
|
||||
title: '制造厂商编号',
|
||||
dataIndex: 'manufactorNo'
|
||||
title: "制造厂商编号",
|
||||
dataIndex: "manufactorNo"
|
||||
},
|
||||
{
|
||||
title: '使用年限',
|
||||
dataIndex: 'lifeYear'
|
||||
title: "使用年限",
|
||||
dataIndex: "lifeYear"
|
||||
},
|
||||
{
|
||||
title: '出厂日期',
|
||||
dataIndex: 'factoryDate',
|
||||
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
|
||||
title: "出厂日期",
|
||||
dataIndex: "factoryDate",
|
||||
customRender: ({ text }) => toDateString(text, "yyyy-MM-dd")
|
||||
},
|
||||
{
|
||||
title: '报废日期',
|
||||
dataIndex: 'scrapDate',
|
||||
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
|
||||
title: "报废日期",
|
||||
dataIndex: "scrapDate",
|
||||
customRender: ({ text }) => toDateString(text, "yyyy-MM-dd")
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
hideInSetting: true
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 200,
|
||||
fixed: "right",
|
||||
align: "center",
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
]);
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: AccessoryParam) => {
|
||||
/* 搜索 */
|
||||
const reload = (where?: AccessoryParam) => {
|
||||
console.log(where);
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Accessory) => {
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Accessory) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
};
|
||||
|
||||
/* 打开批量移动弹窗 */
|
||||
const openMove = () => {
|
||||
/* 打开批量移动弹窗 */
|
||||
const openMove = () => {
|
||||
showMove.value = true;
|
||||
};
|
||||
};
|
||||
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row?: Accessory) => {
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row?: Accessory) => {
|
||||
current.value = row ?? null;
|
||||
showInfo.value = true;
|
||||
};
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: Accessory) => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
/* 删除单个 */
|
||||
const remove = (row: Accessory) => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeAccessory(row.accessoryId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量转移 */
|
||||
const batchMove = (userId) => {
|
||||
console.log(userId, '批量转移0000');
|
||||
console.log(selection.value);
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要删除选中的记录吗?',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
removeBatchAccessory(
|
||||
selection.value.map((d) => {
|
||||
if (loginUser.value.userId === d.userId) {
|
||||
return d.accessoryId;
|
||||
}
|
||||
})
|
||||
)
|
||||
.then((msg) => {
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/* 查询 */
|
||||
const query = () => {
|
||||
/* 批量转移 */
|
||||
const batchMove = (userId) => {
|
||||
console.log(userId, "批量转移0000");
|
||||
console.log(selection.value);
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定要删除选中的记录吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchAccessory(
|
||||
selection.value.map((d) => {
|
||||
if (loginUser.value.userId === d.userId) {
|
||||
return d.accessoryId;
|
||||
}
|
||||
})
|
||||
)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* 查询 */
|
||||
const query = () => {
|
||||
loading.value = true;
|
||||
listCategory()
|
||||
.then((list) => {
|
||||
loading.value = false;
|
||||
const eks: number[] = [];
|
||||
list.forEach((d) => {
|
||||
d.key = d.categoryId;
|
||||
d.value = d.categoryId;
|
||||
if (typeof d.categoryId === 'number') {
|
||||
eks.push(d.categoryId);
|
||||
}
|
||||
.then((list) => {
|
||||
loading.value = false;
|
||||
const eks: number[] = [];
|
||||
list.forEach((d) => {
|
||||
d.key = d.categoryId;
|
||||
d.value = d.categoryId;
|
||||
if (typeof d.categoryId === "number") {
|
||||
eks.push(d.categoryId);
|
||||
}
|
||||
});
|
||||
expandedRowKeys.value = eks;
|
||||
data.value = toTreeData({
|
||||
data: list,
|
||||
idField: "categoryId",
|
||||
parentIdField: "parentId"
|
||||
});
|
||||
if (list.length) {
|
||||
if (typeof list[0].categoryId === "number") {
|
||||
selectedRowKeys.value = [list[0].categoryId];
|
||||
}
|
||||
} else {
|
||||
selectedRowKeys.value = [];
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
expandedRowKeys.value = eks;
|
||||
data.value = toTreeData({
|
||||
data: list,
|
||||
idField: 'categoryId',
|
||||
parentIdField: 'parentId'
|
||||
});
|
||||
if (list.length) {
|
||||
if (typeof list[0].categoryId === 'number') {
|
||||
selectedRowKeys.value = [list[0].categoryId];
|
||||
}
|
||||
} else {
|
||||
selectedRowKeys.value = [];
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: Accessory) => {
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: Accessory) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
}
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
query();
|
||||
query();
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Accessory'
|
||||
};
|
||||
export default {
|
||||
name: "Accessory"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
<a-form-item label="合同编号" v-bind="validateInfos.contactNumber">
|
||||
<a-input
|
||||
allow-clear
|
||||
:maxlength="20"
|
||||
placeholder="请输入合同编号"
|
||||
v-model:value="form.contactNumber"
|
||||
/>
|
||||
@@ -54,37 +53,31 @@
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</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-form-item label="其他说明备注">
|
||||
<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">
|
||||
<SelectCompany
|
||||
:placeholder="`请选择出租单位`"
|
||||
v-model:value="companyName"
|
||||
@done="chooseCompany"
|
||||
/>
|
||||
{{ companyName }}
|
||||
<!-- <SelectCompany-->
|
||||
<!-- :placeholder="`请选择出租单位`"-->
|
||||
<!-- v-model:value="companyName"-->
|
||||
<!-- @done="chooseCompany"-->
|
||||
<!-- />-->
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="承租单位" v-bind="validateInfos.customerId">
|
||||
<SelectCustomer
|
||||
:placeholder="`请选择承租单位`"
|
||||
v-model:value="customerName"
|
||||
@done="chooseCustomer"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="合同金额">
|
||||
<a-input
|
||||
allow-clear
|
||||
:maxlength="20"
|
||||
placeholder="请输入合同金额"
|
||||
v-model:value="form.contractAmount"
|
||||
>
|
||||
<template #addonAfter>
|
||||
<span>元</span>
|
||||
</template>
|
||||
</a-input>
|
||||
{{ customerName }}
|
||||
<!-- <SelectCustomer-->
|
||||
<!-- :placeholder="`请选择承租单位`"-->
|
||||
<!-- v-model:value="customerName"-->
|
||||
<!-- @done="chooseCustomer"-->
|
||||
<!-- />-->
|
||||
</a-form-item>
|
||||
<a-form-item label="截止日期">
|
||||
<a-date-picker
|
||||
@@ -94,6 +87,10 @@
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</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-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="业务负责人">
|
||||
@@ -123,22 +120,48 @@
|
||||
</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 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">
|
||||
<a-col :span="8">
|
||||
<a-form-item label="实际结算金额汇总">
|
||||
<p style="margin-bottom: 0">{{ form.totalSettleAmount }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item label="实收金额汇总">
|
||||
<p style="margin-bottom: 0">{{ form.totalIncomeAmount }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item label="欠收金额汇总">
|
||||
<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 justify-between items-center">
|
||||
<span>合同电子存档</span>
|
||||
<UploadFile @update:value="uploadFile" />
|
||||
</div>
|
||||
<div class="flex justify-start flex-wrap items-start">
|
||||
<a-tag closable @close="delFile(index)" v-for="(item, index) in contractFileList" :key="index">{{ item.path }}
|
||||
</a-tag>
|
||||
<div>
|
||||
<p>合同电子存档</p>
|
||||
<div class="flex justify-start">
|
||||
<a-upload
|
||||
v-model:file-list="fileList"
|
||||
name="file"
|
||||
action="https://file.wsdns.cn/api/file/image"
|
||||
:headers="{ Authorization: token }"
|
||||
@change="onFileUpload"
|
||||
>
|
||||
<a-button>
|
||||
<upload-outlined />
|
||||
上传
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-start items-center"
|
||||
@@ -153,9 +176,12 @@
|
||||
<a-col :span="3" class="p-05 border-r-white">
|
||||
<span>设备名称</span>
|
||||
</a-col>
|
||||
<a-col :span="3" class="p-05 border-r-white">
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<span>规格型号</span>
|
||||
</a-col>
|
||||
<a-col :span="3" class="p-05 border-r-white">
|
||||
<span>备案编号</span>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<span>签订数量</span>
|
||||
</a-col>
|
||||
@@ -163,21 +189,21 @@
|
||||
<span>计划租期(月)</span>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<span>租金(元)</span>
|
||||
<span>租金(元/月)</span>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<span>进退场费(元)</span>
|
||||
<span>进退场费(元/次)</span>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<span>劳务费用(元)</span>
|
||||
<span>劳务费用(元/月)</span>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<span>其他费用(元)</span>
|
||||
<span>其他费用(元/次)</span>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<span>预埋费(元)</span>
|
||||
<span>预埋费(元/次)</span>
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<a-col :span="1" class="p-05 border-r-white">
|
||||
<span>备注</span>
|
||||
</a-col>
|
||||
<a-col :span="1" class="p-05">
|
||||
@@ -192,20 +218,18 @@
|
||||
<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"
|
||||
v-model:value="contractEquipmentList[index].equipmentName">
|
||||
<a-select-option v-for="(item, index) in equipmentList" :key="index" :value="item.name">{{ item.name
|
||||
}}
|
||||
<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-col>
|
||||
<a-col :span="3" class="p-05 border-r-white">
|
||||
<a-select placeholder="必选项" style="width: 100%" size="small"
|
||||
v-model:value="contractEquipmentList[index].equipmentModel">
|
||||
<a-select-option v-for="(item, index) in equipmentList" :key="index" :value="item.model">{{ item.model
|
||||
}}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<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">
|
||||
@@ -233,10 +257,10 @@
|
||||
type="number" />
|
||||
</a-col>
|
||||
<a-col :span="2" class="p-05 border-r-white">
|
||||
<a-input v-model:value="contractEquipmentList[index].preBuryAmount" size="small" placeholder="必填项"
|
||||
<a-input v-model:value="contractEquipmentList[index].preBuryAmount" size="small"
|
||||
type="number" />
|
||||
</a-col>
|
||||
<a-col :span="2" 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-col>
|
||||
<a-col :span="1" class="p-05">
|
||||
@@ -262,7 +286,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, computed } from "vue";
|
||||
import { Form, message } from "ant-design-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";
|
||||
@@ -273,7 +297,7 @@ import { ContractFile } from "@/api/tower/contractFile/model";
|
||||
import {
|
||||
PlusOutlined,
|
||||
UnorderedListOutlined,
|
||||
CloseCircleOutlined
|
||||
CloseCircleOutlined, UploadOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import { ContractEquipment } from "@/api/tower/contractEquipment/model";
|
||||
import { TowerModel } from "@/api/tower/model/model";
|
||||
@@ -282,10 +306,16 @@ 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 now = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||
|
||||
@@ -322,8 +352,13 @@ const form = reactive<Contract>({
|
||||
endDate: "",
|
||||
contractAmount: undefined,
|
||||
contactAgreeAmount: undefined,
|
||||
totalSettleAmount: 0,
|
||||
totalIncomeAmount: 0,
|
||||
isInStock: 0,
|
||||
autoSettle: 0
|
||||
autoSettle: 0,
|
||||
payRate: undefined,
|
||||
remark: "",
|
||||
fileList: "[]"
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
@@ -340,13 +375,13 @@ const rules = reactive({
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
contactNumber: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入合同编号",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
// contactNumber: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: "请输入合同编号",
|
||||
// trigger: "blur"
|
||||
// }
|
||||
// ],
|
||||
companyId: [
|
||||
{
|
||||
required: true,
|
||||
@@ -365,8 +400,15 @@ const rules = reactive({
|
||||
|
||||
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>();
|
||||
@@ -391,6 +433,25 @@ const changeAutoSettle = (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 contractFileList = ref<ContractFile[]>([]);
|
||||
const uploadFile = path => {
|
||||
contractFileList.value.push({ path, contractId: 0, userId: loginUser.value.userId });
|
||||
@@ -401,17 +462,22 @@ const delFile = index => {
|
||||
};
|
||||
|
||||
const getContractFileList = async () => {
|
||||
contractFileList.value = await listContractFile({ contactId: props.data?.contractId });
|
||||
contractFileList.value = await listContractFile({ contractId: props.data?.contractId });
|
||||
};
|
||||
|
||||
const equipmentList = ref<TowerModel[]>([]);
|
||||
const equipmentList = ref<TowerEquipment[]>([]);
|
||||
const getEquipmentList = async () => {
|
||||
equipmentList.value = await listTowerModel();
|
||||
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({ contactId: props.data?.contractId });
|
||||
contractEquipmentList.value = await listContractEquipment({ contractId: props.data?.contractId });
|
||||
};
|
||||
|
||||
const chooseEquipmentName = (res, index) => {
|
||||
@@ -426,6 +492,7 @@ const addEquipment = () => {
|
||||
contractEquipmentList.value.push({
|
||||
contractEquipmentId: null,
|
||||
contractId: null,
|
||||
equipmentId: undefined,
|
||||
equipmentName: "",
|
||||
equipmentModel: "",
|
||||
num: null,
|
||||
@@ -456,8 +523,7 @@ const save = () => {
|
||||
...form
|
||||
};
|
||||
for (let i = 0; i < contractEquipmentList.value.length; i++) {
|
||||
if (!contractEquipmentList.value[i].equipmentName) {
|
||||
console.log(contractEquipmentList.value[i].equipmentName);
|
||||
if (!contractEquipmentList.value[i].equipmentId) {
|
||||
loading.value = false;
|
||||
message.error("请选择设备");
|
||||
return;
|
||||
@@ -497,11 +563,6 @@ const save = () => {
|
||||
message.error("请输入其他费用");
|
||||
return;
|
||||
}
|
||||
if (contractEquipmentList.value[i].preBuryAmount === null) {
|
||||
loading.value = false;
|
||||
message.error("请输入预埋费");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 转字符串
|
||||
const saveOrUpdate = isUpdate.value ? updateContract : addContract;
|
||||
@@ -509,11 +570,11 @@ const save = () => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
const contractId = res.data;
|
||||
if (contractFileList.value.length > 0) await saveFileList(contractId);
|
||||
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);
|
||||
message.success(res?.message);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
|
||||
@@ -536,11 +597,19 @@ const saveEquipmentList = async (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);
|
||||
@@ -550,11 +619,16 @@ watch(
|
||||
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 {
|
||||
projectName.value = customerName.value = companyName.value = "";
|
||||
contractFileList.value = [];
|
||||
fileList.value = [];
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,9 +64,19 @@
|
||||
<template v-if="column.key === 'workerAmountSum'">
|
||||
<span>{{ record.rentMonth * record.workerAmount }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'otherAmountCalMode'">
|
||||
<a-select style="width: 100px" size="small"
|
||||
v-model:value="record.otherAmountCalMode">
|
||||
<a-select-option :value="0">按月</a-select-option>
|
||||
<a-select-option :value="1">一次</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-if="column.key === 'otherAmount'">
|
||||
<a-input v-model:value="record.otherAmount" type="number" />
|
||||
</template>
|
||||
<template v-if="column.key === 'preBuryAmount'">
|
||||
<a-input v-model:value="record.preBuryAmount" type="number" />
|
||||
</template>
|
||||
<template v-if="column.key === 'remark'">
|
||||
<a-input v-model:value="record.remark" />
|
||||
</template>
|
||||
@@ -94,7 +104,9 @@
|
||||
<a-table-summary-cell>
|
||||
{{ totals.workerAmountSum }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell>
|
||||
{{ totals.otherAmountSum }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
</a-table-summary-row>
|
||||
</template>
|
||||
@@ -167,6 +179,9 @@ import { ContractSettleRule } from "@/api/tower/contractSettle/rule/model";
|
||||
import { updateContract } from "@/api/tower/contract";
|
||||
import { addBatchContractSettleEquipment, listContractSettleEquipment } from "@/api/tower/contractSettle/equipment";
|
||||
import { addBatchContractSettleRule, listContractSettleRule } from "@/api/tower/contractSettle/rule";
|
||||
import { TowerEquipment } from "@/api/tower/equipment/model";
|
||||
import { listContractEquipment } from "@/api/tower/contractEquipment";
|
||||
import { ContractEquipment } from "@/api/tower/contractEquipment/model";
|
||||
|
||||
|
||||
const userStore = useUserStore();
|
||||
@@ -199,7 +214,7 @@ const maxable = ref(true);
|
||||
|
||||
const showSelectEquip = ref<Boolean>(false);
|
||||
|
||||
const onSelectEquip = data => {
|
||||
const onSelectEquip = (data: TowerEquipment) => {
|
||||
addEquipment(data);
|
||||
};
|
||||
|
||||
@@ -275,6 +290,17 @@ const equipmentColumns = ref<ColumnItem[]>([
|
||||
dataIndex: "otherAmount",
|
||||
key: "otherAmount"
|
||||
},
|
||||
{
|
||||
title: "其他费用结算模式",
|
||||
dataIndex: "otherAmountCalMode",
|
||||
key: "otherAmountCalMode",
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: "预埋费(元)",
|
||||
dataIndex: "preBuryAmount",
|
||||
key: "preBuryAmount"
|
||||
},
|
||||
{
|
||||
title: "备注",
|
||||
dataIndex: "remark",
|
||||
@@ -286,23 +312,49 @@ const equipmentColumns = ref<ColumnItem[]>([
|
||||
key: "action"
|
||||
}
|
||||
]);
|
||||
|
||||
const equipmentList = ref<ContractEquipment[]>([]);
|
||||
const getEquipmentList = async () => {
|
||||
equipmentList.value = await listContractEquipment({ contractId: props.data?.contractId });
|
||||
};
|
||||
|
||||
const settleEquipmentList = ref<ContractSettleEquipment[]>([]);
|
||||
const getSettleEquipmentList = async () => {
|
||||
settleEquipmentList.value = await listContractSettleEquipment({ contractId: contract.contractId });
|
||||
if (settleEquipmentList.value.length === 0) {
|
||||
equipmentList.value.forEach(item => {
|
||||
addEquipment(item, item.planRentMonth, item.rentAmount, item.inOutAmount, item.workerAmount, item.otherAmount, item.otherAmount);
|
||||
});
|
||||
}
|
||||
};
|
||||
const addEquipment = data => {
|
||||
|
||||
const contractEquipmentList = ref<ContractEquipment[]>([]);
|
||||
const getContractEquipmentList = async () => {
|
||||
contractEquipmentList.value = await listContractEquipment({ contractId: props.data?.contractId });
|
||||
contractEquipmentList.value.forEach(data => {
|
||||
data.name = data.equipmentName
|
||||
data.model = data?.equipmentModel
|
||||
addEquipment(data);
|
||||
});
|
||||
};
|
||||
|
||||
const addEquipment = (data, rentMonth = 0, rentAmount = 0, inOutAmount = 0, workerAmount = 0, otherAmount = 0, preBuryAmount = 0) => {
|
||||
settleEquipmentList.value = [...settleEquipmentList.value, {
|
||||
contractSettleId: 0,
|
||||
equipmentId: data.equipmentId,
|
||||
contractId: props.data?.contractId,
|
||||
equipmentName: data.name,
|
||||
equipmentModel: data.model,
|
||||
factoryNo: data.factoryNo,
|
||||
filingNo: data.filingNo,
|
||||
equipmentNo: data.equipmentNo,
|
||||
rentMonth: 0,
|
||||
rentAmount: 0,
|
||||
inOutAmount: 0,
|
||||
workerAmount: 0,
|
||||
otherAmount: 0,
|
||||
rentMonth,
|
||||
rentAmount,
|
||||
inOutAmount,
|
||||
workerAmount,
|
||||
otherAmount,
|
||||
otherAmountCalMode: 0,
|
||||
preBuryAmount,
|
||||
remark: "",
|
||||
userId: loginUser.value.userId
|
||||
}];
|
||||
@@ -364,12 +416,15 @@ const delRule = index => {
|
||||
const totals = computed(() => {
|
||||
let rentAmountSum = 0;
|
||||
let workerAmountSum = 0;
|
||||
let otherAmountSum = 0;
|
||||
|
||||
settleEquipmentList.value.forEach(({ rentMonth, rentAmount, workerAmount }) => {
|
||||
settleEquipmentList.value.forEach(({ rentMonth, rentAmount, workerAmount, otherAmountCalMode, otherAmount }) => {
|
||||
rentAmountSum += rentMonth * rentAmount;
|
||||
workerAmountSum += rentMonth * workerAmount;
|
||||
if (otherAmountCalMode === 0) otherAmountSum += rentMonth * otherAmount;
|
||||
else otherAmountSum += otherAmount;
|
||||
});
|
||||
return { rentAmountSum, workerAmountSum };
|
||||
return { rentAmountSum, workerAmountSum, otherAmountSum };
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
@@ -377,12 +432,6 @@ const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
const equipmentList = ref<TowerModel[]>([]);
|
||||
const getEquipmentList = async () => {
|
||||
equipmentList.value = await listTowerModel();
|
||||
};
|
||||
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
if (contract.settleMethod === undefined) {
|
||||
@@ -408,28 +457,30 @@ const save = () => {
|
||||
}
|
||||
}
|
||||
loading.value = true;
|
||||
updateContract(contract);
|
||||
addBatchContractSettleEquipment(settleEquipmentList.value);
|
||||
addBatchContractSettleRule(settleRuleList.value);
|
||||
loading.value = false;
|
||||
// message.success(res.message);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
Promise.all([updateContract(contract), addBatchContractSettleEquipment(settleEquipmentList.value), addBatchContractSettleRule(settleRuleList.value)])
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
// message.success(res.message);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
async (visible) => {
|
||||
if (visible) {
|
||||
for (let i = 2; i < 28; i++) dateList.value.push(i);
|
||||
getEquipmentList();
|
||||
await getEquipmentList();
|
||||
settleEquipmentList.value = [];
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(contract, props.data);
|
||||
getSettleEquipmentList();
|
||||
getSettleRuleList();
|
||||
await getSettleEquipmentList();
|
||||
await getSettleRuleList();
|
||||
isUpdate.value = true;
|
||||
} else {
|
||||
await getContractEquipmentList();
|
||||
isUpdate.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,12 @@
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'needPay'">
|
||||
<span v-if="record.payRate && record.totalSettleAmount">{{ (record.payRate / 100 * record.totalSettleAmount).toFixed(2) }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalUnReceivableAmount'">
|
||||
<p>{{ record.totalSettleAmount - record.totalIncomeAmount }}</p>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openSettle(record)">合同结算设置</a>
|
||||
@@ -131,9 +137,8 @@
|
||||
},
|
||||
{
|
||||
title: '合同编号',
|
||||
dataIndex: 'contractNumber',
|
||||
key: 'contractNumber',
|
||||
ellipsis: true
|
||||
dataIndex: 'contactNumber',
|
||||
key: 'contactNumber'
|
||||
},
|
||||
{
|
||||
title: '项目名称',
|
||||
@@ -141,11 +146,24 @@
|
||||
},
|
||||
{
|
||||
title: '预计产值',
|
||||
dataIndex: ''
|
||||
dataIndex: 'contractAmount'
|
||||
},
|
||||
{
|
||||
title: '结算产值',
|
||||
dataIndex: ''
|
||||
title: '实际结算金额',
|
||||
dataIndex: 'totalSettleAmount'
|
||||
},
|
||||
{
|
||||
title: '实际收款金额',
|
||||
dataIndex: 'totalIncomeAmount'
|
||||
},
|
||||
{
|
||||
title: '累计开票金额',
|
||||
dataIndex: 'totalInvoicingAmount'
|
||||
},
|
||||
{
|
||||
title: '欠收金额',
|
||||
dataIndex: 'totalUnReceivableAmount',
|
||||
key: 'totalUnReceivableAmount'
|
||||
},
|
||||
{
|
||||
title: '业务联系人',
|
||||
@@ -170,7 +188,6 @@
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: ContractParam) => {
|
||||
console.log(where);
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
|
||||
102
src/views/tower/customer/components/import.vue
Normal file
102
src/views/tower/customer/components/import.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="600"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
:title="`导入客户`"
|
||||
:body-style="{ paddingBottom: '28px' }"
|
||||
@update:visible="updateVisible"
|
||||
:footer="null"
|
||||
>
|
||||
<a-upload-dragger
|
||||
name="file"
|
||||
:show-upload-list="false"
|
||||
accept=".xls,.xlsx"
|
||||
:before-upload="handleImport"
|
||||
>
|
||||
<p class="ant-upload-drag-icon">
|
||||
<InboxOutlined />
|
||||
</p>
|
||||
<p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
|
||||
<p class="ant-upload-hint" style="max-width: 550px">
|
||||
提示:附件上传中,请不要做任何操作! 支持的文件类型为*.xls, *.xlsx!
|
||||
</p>
|
||||
</a-upload-dragger>
|
||||
<div style="margin: 20px auto; display: flex; justify-content: center">
|
||||
<a
|
||||
href="http://1.14.159.185:10042/template/customer_template.xlsx"
|
||||
target="_blank"
|
||||
>下载客户导入模板</a
|
||||
>
|
||||
</div>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { InboxOutlined } from "@ant-design/icons-vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import { addBatchTowerEquipment } from "@/api/tower/equipment";
|
||||
import { read, utils } from "xlsx";
|
||||
import { ref } from "vue";
|
||||
import type { Customer } from '@/api/oa/customer/model';
|
||||
import { addBatchCustomer } from "@/api/oa/customer";
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 导入的数据
|
||||
const importData = ref<Customer[]>([]);
|
||||
const handleImport = (file: File) => {
|
||||
if (
|
||||
![
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
].includes(file.type)
|
||||
) {
|
||||
message.error("只能选择 excel 文件");
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
message.error("大小不能超过 20MB");
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
importData.value = []
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target?.result as any);
|
||||
const workbook = read(data, { type: "array" });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
console.log(aoa);
|
||||
aoa.slice(1).map((d) => {
|
||||
if (d[1] && d[0]) {
|
||||
importData.value.push({
|
||||
name: d[0],
|
||||
creditCode: d[1],
|
||||
fullName: d[2],
|
||||
address: d[3],
|
||||
contact: d[4],
|
||||
telPhone: d[5],
|
||||
phone: d[6],
|
||||
});
|
||||
}
|
||||
});
|
||||
addBatchCustomer(importData.value).then(() => {
|
||||
message.success("导入成功");
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
};
|
||||
</script>
|
||||
@@ -7,15 +7,11 @@
|
||||
</template>
|
||||
<span>添加客户</span>
|
||||
</a-button>
|
||||
<a-upload
|
||||
:before-upload="importBatch"
|
||||
:show-upload-list="false"
|
||||
accept=".xls,.xlsx"
|
||||
>
|
||||
<a-button class="ele-btn-icon"> <DownloadOutlined />批量导入 </a-button>
|
||||
</a-upload>
|
||||
<a-button class="ele-btn-icon">
|
||||
<span>下载客户模板</span>
|
||||
<a-button class="ele-btn-icon" @click="openImport">
|
||||
<template #icon>
|
||||
<UploadOutlined />
|
||||
</template>
|
||||
<span>导入客户</span>
|
||||
</a-button>
|
||||
<a-upload
|
||||
:before-upload="importBatch"
|
||||
@@ -50,6 +46,7 @@
|
||||
@search="search"
|
||||
/>
|
||||
</a-space>
|
||||
<Import v-model:visible="showImport" @done="search" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -65,6 +62,7 @@
|
||||
import { utils, read } from 'xlsx';
|
||||
// import { assignObject } from 'ele-admin-pro';
|
||||
import { message } from 'ant-design-vue/es';
|
||||
import Import from "@/views/tower/customer/components/import.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -216,6 +214,11 @@
|
||||
search();
|
||||
};
|
||||
|
||||
const showImport = ref(false)
|
||||
const openImport = () => {
|
||||
showImport.value = true;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.selection,
|
||||
() => {}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,87 +25,90 @@
|
||||
</a-upload-dragger>
|
||||
<div style="margin: 20px auto; display: flex; justify-content: center">
|
||||
<a
|
||||
href="https://file.wsdns.cn/download/20230523/2f5ffa06b0684e138184c6786f6fbb68.xlsx"
|
||||
href="http://1.14.159.185:10042/template/2f5ffa06b0684e138184c6786f6fbb68.xlsx"
|
||||
target="_blank"
|
||||
>下载设备导入模板</a
|
||||
>下载设备导入模板</a
|
||||
>
|
||||
</div>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { InboxOutlined } from '@ant-design/icons-vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { addBatchTowerEquipment } from '@/api/tower/equipment';
|
||||
import { TowerEquipment } from '@/api/tower/equipment/model';
|
||||
import { read, utils } from 'xlsx';
|
||||
import { ref } from 'vue';
|
||||
import { InboxOutlined } from "@ant-design/icons-vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import { addBatchTowerEquipment } from "@/api/tower/equipment";
|
||||
import { TowerEquipment } from "@/api/tower/equipment/model";
|
||||
import { read, utils } from "xlsx";
|
||||
import { ref } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done'): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 导入的数据
|
||||
const importData = ref<TowerEquipment[]>([]);
|
||||
const handleImport = (file: File) => {
|
||||
if (
|
||||
![
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
].includes(file.type)
|
||||
) {
|
||||
message.error('只能选择 excel 文件');
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
message.error('大小不能超过 20MB');
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target?.result as any);
|
||||
const workbook = read(data, { type: 'array' });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
console.log(aoa);
|
||||
aoa.slice(1).map((d) => {
|
||||
const array = ['闲置', '报废', '注销', '转卖'];
|
||||
importData.value.push({
|
||||
status: array.indexOf(d[0]),
|
||||
name: d[1],
|
||||
factoryNo: d[2],
|
||||
model: d[3],
|
||||
manufactor: d[4],
|
||||
buyDate: d[5],
|
||||
filingNo: d[6],
|
||||
factoryDate: d[7],
|
||||
company: d[8],
|
||||
source: d[9],
|
||||
warehouse: d[10],
|
||||
users: d[11],
|
||||
equipmentNo: d[12],
|
||||
ratedLoad: d[13],
|
||||
maxLiftingHeight: d[14],
|
||||
armLength: d[15],
|
||||
currentLocation: d[16],
|
||||
machineNo: d[17]
|
||||
});
|
||||
});
|
||||
addBatchTowerEquipment(importData.value).then(() => {
|
||||
message.success('导入成功');
|
||||
updateVisible(false);
|
||||
emit('done');
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
// 导入的数据
|
||||
const importData = ref<TowerEquipment[]>([]);
|
||||
const handleImport = (file: File) => {
|
||||
if (
|
||||
![
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
].includes(file.type)
|
||||
) {
|
||||
message.error("只能选择 excel 文件");
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
message.error("大小不能超过 20MB");
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
importData.value = []
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target?.result as any);
|
||||
const workbook = read(data, { type: "array" });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
aoa.slice(1).map((d) => {
|
||||
const array = ["闲置", "报废", "注销", "转卖", "在用", "停工"];
|
||||
if (d[1]) {
|
||||
importData.value.push({
|
||||
name: d[1],
|
||||
filingNo: d[2],
|
||||
factoryNo: d[3],
|
||||
model: d[4],
|
||||
manufactor: d[5],
|
||||
company: d[6],
|
||||
factoryDate: d[7],
|
||||
status: array.indexOf(d[8]),
|
||||
lifeYear: d[9],
|
||||
buyDate: d[10],
|
||||
source: d[11],
|
||||
warehouse: d[12],
|
||||
users: d[13],
|
||||
equipmentNo: d[14],
|
||||
ratedLoad: d[15],
|
||||
maxLiftingHeight: d[16],
|
||||
armLength: d[17],
|
||||
scrapDate: (d[7] && d[9]) ? (dayjs(d[7] ).add(parseInt(d[9]) , 'year').format('YYYY-MM-DD')) : ''
|
||||
});
|
||||
}
|
||||
});
|
||||
addBatchTowerEquipment(importData.value).then(() => {
|
||||
message.success("导入成功");
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
};
|
||||
</script>
|
||||
|
||||
44
src/views/tower/equipment/components/project-list.vue
Normal file
44
src/views/tower/equipment/components/project-list.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<ele-modal
|
||||
width="80%"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
:maxable="maxable"
|
||||
title="历史项目"
|
||||
:body-style="{ paddingBottom: '28px' }"
|
||||
@update:visible="updateVisible"
|
||||
>
|
||||
<a-card v-for="(item, index) in data?.projectList" :key="index">
|
||||
<a-descriptions :title="item.projectName">
|
||||
<a-descriptions-item label="项目地址">{{ item.projectRegion + item.projectAddress }}</a-descriptions-item>
|
||||
<a-descriptions-item label="主管部门">{{ item.competentDepartment }}</a-descriptions-item>
|
||||
<a-descriptions-item label="租赁单位">{{ item.companyName }}</a-descriptions-item>
|
||||
<a-descriptions-item label="承租单位">{{ item.customerName }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
</ele-modal>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import { TowerEquipment } from "@/api/tower/equipment/model";
|
||||
import { WORKSHEET_WORK_TYPE } from "@/api/tower/worksheet/model";
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: TowerEquipment | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
const maxable = ref(true);
|
||||
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
</script>
|
||||
@@ -1,203 +1,237 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<a-space :size="10" style="flex-wrap: wrap">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
<span>添加设备</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
:disabled="selection.length === 0"
|
||||
@click="removeBatch"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
<span>批量删除</span>
|
||||
</a-button>
|
||||
<a-button class="ele-btn-icon" @click="openImport">
|
||||
<template #icon>
|
||||
<UploadOutlined />
|
||||
</template>
|
||||
<span>导入设备</span>
|
||||
</a-button>
|
||||
<a-button class="ele-btn-icon" @click="handleExport">
|
||||
<template #icon>
|
||||
<DownloadOutlined />
|
||||
</template>
|
||||
<span>导出设备</span>
|
||||
</a-button>
|
||||
<a-radio-group v-model:value="status" @change="handleStatus">
|
||||
<a-radio-button :value="1">报废</a-radio-button>
|
||||
<a-radio-button :value="2">注销</a-radio-button>
|
||||
<a-radio-button :value="0">恢复</a-radio-button>
|
||||
<a-radio-button :value="3">转卖</a-radio-button>
|
||||
</a-radio-group>
|
||||
<a-input-search
|
||||
allow-clear
|
||||
placeholder="请输入关键词"
|
||||
v-model:value="searchText"
|
||||
@pressEnter="search"
|
||||
@search="search"
|
||||
/>
|
||||
<!-- 导入弹窗 -->
|
||||
<Import v-model:visible="showImport" @done="search" />
|
||||
</a-space>
|
||||
<a-space :size="10" style="flex-wrap: wrap">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
<span>添加设备</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
:disabled="selection.length === 0"
|
||||
@click="removeBatch"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
<span>批量删除</span>
|
||||
</a-button>
|
||||
<a-button class="ele-btn-icon" @click="openImport">
|
||||
<template #icon>
|
||||
<UploadOutlined />
|
||||
</template>
|
||||
<span>导入设备</span>
|
||||
</a-button>
|
||||
<a-button class="ele-btn-icon" @click="handleExport">
|
||||
<template #icon>
|
||||
<DownloadOutlined />
|
||||
</template>
|
||||
<span>导出设备</span>
|
||||
</a-button>
|
||||
<a-radio-group v-model:value="status" @change="handleStatus" :disabled="selection.length === 0">
|
||||
<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-button :value="4">在用</a-radio-button>
|
||||
<a-radio-button :value="5">停工</a-radio-button>
|
||||
</a-radio-group>
|
||||
<a-select placeholder="设备状态筛选" style="width: 250px" @change="search"
|
||||
@clear="search"
|
||||
v-model:value="statusFilter" allow-clear>
|
||||
<a-select-option :value="null">全部</a-select-option>
|
||||
<a-select-option :value="0">闲置</a-select-option>
|
||||
<a-select-option :value="1">报废</a-select-option>
|
||||
<a-select-option :value="2">注销</a-select-option>
|
||||
<a-select-option :value="3">转卖</a-select-option>
|
||||
<a-select-option :value="4">在用</a-select-option>
|
||||
<a-select-option :value="5">停工</a-select-option>
|
||||
</a-select>
|
||||
<a-input-search
|
||||
allow-clear
|
||||
placeholder="请输入关键词"
|
||||
v-model:value="searchText"
|
||||
@pressEnter="search"
|
||||
@search="search"
|
||||
/>
|
||||
<a-input-search
|
||||
:min="0"
|
||||
type="number"
|
||||
allow-clear
|
||||
placeholder="剩余可用年份筛选"
|
||||
v-model:value="yearFilter"
|
||||
@pressEnter="search"
|
||||
@search="search"
|
||||
/>
|
||||
<!-- 导入弹窗 -->
|
||||
<Import v-model:visible="showImport" @done="search" />
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
import {
|
||||
PlusOutlined,
|
||||
UploadOutlined,
|
||||
DownloadOutlined,
|
||||
DeleteOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import useSearch from '@/utils/use-search';
|
||||
import { ref, watch } from 'vue';
|
||||
import { utils, writeFile } from 'xlsx';
|
||||
import { TowerEquipment } from '@/api/tower/equipment/model';
|
||||
import { TowerEquipmentParam } from '@/api/tower/equipment/model';
|
||||
import Import from './import.vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
} from "@ant-design/icons-vue";
|
||||
import useSearch from "@/utils/use-search";
|
||||
import { ref, watch } from "vue";
|
||||
import { utils, writeFile } from "xlsx";
|
||||
import { TowerEquipment } from "@/api/tower/equipment/model";
|
||||
import { TowerEquipmentParam } from "@/api/tower/equipment/model";
|
||||
import Import from "./import.vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import { ContractSettleMethod } from "@/api/tower/contract/model";
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
// 选中的角色
|
||||
selection?: [];
|
||||
// 选中的角色
|
||||
selection?: [];
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search', where?: TowerEquipmentParam): void;
|
||||
(e: 'add'): void;
|
||||
(e: 'remove'): void;
|
||||
(e: 'update', status?: number): void;
|
||||
(e: 'import'): void;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: "search", where?: TowerEquipmentParam): void;
|
||||
(e: "add"): void;
|
||||
(e: "remove"): void;
|
||||
(e: "update", status?: number): void;
|
||||
(e: "import"): void;
|
||||
}>();
|
||||
|
||||
// 表单数据
|
||||
const { where, resetFields } = useSearch<TowerEquipmentParam>({
|
||||
// 表单数据
|
||||
const { where, resetFields } = useSearch<TowerEquipmentParam>({
|
||||
equipmentId: undefined,
|
||||
name: undefined,
|
||||
keywords: ''
|
||||
});
|
||||
// 下来选项
|
||||
const type = ref('keywords');
|
||||
// 搜索内容
|
||||
const searchText = ref('');
|
||||
// 状态
|
||||
const status = ref<number>();
|
||||
// 是否显示导入弹窗
|
||||
const showImport = ref(false);
|
||||
keywords: "",
|
||||
status: undefined,
|
||||
yearFilter: undefined,
|
||||
});
|
||||
// 下来选项
|
||||
const type = ref("keywords");
|
||||
// 搜索内容
|
||||
const searchText = ref("");
|
||||
const yearFilter = ref<number>();
|
||||
const statusFilter = ref(undefined);
|
||||
// 状态
|
||||
const status = ref<number>();
|
||||
// 是否显示导入弹窗
|
||||
const showImport = ref(false);
|
||||
|
||||
/* 搜索 */
|
||||
const search = () => {
|
||||
/* 搜索 */
|
||||
const search = () => {
|
||||
resetFields();
|
||||
if (type.value == 'keywords') {
|
||||
where.keywords = searchText.value;
|
||||
if (type.value == "keywords") {
|
||||
where.keywords = searchText.value;
|
||||
}
|
||||
emit('search', {
|
||||
...where
|
||||
if (statusFilter.value !== undefined) {
|
||||
where.status = statusFilter.value;
|
||||
}
|
||||
if (yearFilter.value !== undefined) {
|
||||
where.yearFilter = yearFilter.value;
|
||||
}
|
||||
emit("search", {
|
||||
...where
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExport = () => {
|
||||
// 导出
|
||||
const handleExport = () => {
|
||||
if (!props.selection?.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
const array: (string | number)[][] = [
|
||||
[
|
||||
'设备状态',
|
||||
'设备名称',
|
||||
'出厂编号',
|
||||
'设备型号',
|
||||
'制造厂商',
|
||||
'采购日期',
|
||||
'备案编号',
|
||||
'出厂日期',
|
||||
'产权单位',
|
||||
'设备来源',
|
||||
'所属仓库',
|
||||
'所属人员',
|
||||
'自编号',
|
||||
'额定载重',
|
||||
'最大起升高度(m)',
|
||||
'臂长',
|
||||
'当前位置',
|
||||
'楼号'
|
||||
]
|
||||
[
|
||||
"设备状态",
|
||||
"设备名称",
|
||||
"出厂编号",
|
||||
"设备型号",
|
||||
"制造厂商",
|
||||
"采购日期",
|
||||
"备案编号",
|
||||
"出厂日期",
|
||||
"产权单位",
|
||||
"设备来源",
|
||||
"所属仓库",
|
||||
"所属人员",
|
||||
"自编号",
|
||||
"额定载重",
|
||||
"最大起升高度(m)",
|
||||
"臂长",
|
||||
"当前位置",
|
||||
"楼号"
|
||||
]
|
||||
];
|
||||
|
||||
props.selection?.forEach((d: TowerEquipment) => {
|
||||
array.push([
|
||||
`${['闲置', '报废', '注销', '转卖'][Number(d.status)]}`,
|
||||
`${d.name}`,
|
||||
`${d.factoryNo}`,
|
||||
`${d.model}`,
|
||||
`${d.manufactor}`,
|
||||
`${d.buyDate ? d.buyDate : ''}`,
|
||||
`${d.filingNo}`,
|
||||
`${d.factoryDate ? d.factoryDate : ''}`,
|
||||
`${d.company}`,
|
||||
`${d.source}`,
|
||||
`${d.warehouse}`,
|
||||
`${d.users}`,
|
||||
`${d.equipmentNo}`,
|
||||
`${d.ratedLoad}`,
|
||||
`${d.maxLiftingHeight}`,
|
||||
`${d.armLength}`,
|
||||
`${d.currentLocation}`,
|
||||
`${d.machineNo}`
|
||||
]);
|
||||
array.push([
|
||||
`${["闲置", "报废", "注销", "转卖", "在用", "停工"][Number(d.status)]}`,
|
||||
`${d.name}`,
|
||||
`${d.factoryNo}`,
|
||||
`${d.model}`,
|
||||
`${d.manufactor}`,
|
||||
`${d.buyDate ? d.buyDate : ""}`,
|
||||
`${d.filingNo}`,
|
||||
`${d.factoryDate ? d.factoryDate : ""}`,
|
||||
`${d.company}`,
|
||||
`${d.source}`,
|
||||
`${d.warehouse}`,
|
||||
`${d.users}`,
|
||||
`${d.equipmentNo}`,
|
||||
`${d.ratedLoad}`,
|
||||
`${d.maxLiftingHeight}`,
|
||||
`${d.armLength}`,
|
||||
`${d.currentLocation}`,
|
||||
`${d.machineNo}`
|
||||
]);
|
||||
});
|
||||
const sheetName = '设备导出列表';
|
||||
const sheetName = "设备导出列表";
|
||||
const workbook = {
|
||||
SheetNames: [sheetName],
|
||||
Sheets: {}
|
||||
SheetNames: [sheetName],
|
||||
Sheets: {}
|
||||
};
|
||||
const sheet = utils.aoa_to_sheet(array);
|
||||
workbook.Sheets[sheetName] = sheet;
|
||||
// 设置列宽
|
||||
sheet['!cols'] = [
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 20 },
|
||||
{ wch: 40 },
|
||||
{ wch: 10 }
|
||||
sheet["!cols"] = [
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 20 },
|
||||
{ wch: 40 },
|
||||
{ wch: 10 }
|
||||
];
|
||||
writeFile(workbook, '导出设备管理表.xlsx');
|
||||
};
|
||||
writeFile(workbook, "导出设备管理表.xlsx");
|
||||
};
|
||||
|
||||
// 发布设备
|
||||
const add = () => {
|
||||
emit('add');
|
||||
};
|
||||
// 发布设备
|
||||
const add = () => {
|
||||
emit("add");
|
||||
};
|
||||
|
||||
// 导入
|
||||
const openImport = () => {
|
||||
// 导入
|
||||
const openImport = () => {
|
||||
showImport.value = true;
|
||||
};
|
||||
};
|
||||
|
||||
const handleStatus = () => {
|
||||
emit('update', status.value);
|
||||
};
|
||||
const handleStatus = () => {
|
||||
emit("update", status.value);
|
||||
};
|
||||
|
||||
// 批量删除
|
||||
const removeBatch = () => {
|
||||
emit('remove');
|
||||
};
|
||||
// 批量删除
|
||||
const removeBatch = () => {
|
||||
emit("remove");
|
||||
};
|
||||
|
||||
watch(
|
||||
watch(
|
||||
() => props.selection,
|
||||
() => {}
|
||||
);
|
||||
() => {
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -1,282 +1,348 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false">
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="equipmentId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
:customRow="customRow"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 1200 }"
|
||||
class="sys-org-table"
|
||||
:striped="true"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@update="handleStatus"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'nickname'">
|
||||
{{ record.nickname }}
|
||||
<div>
|
||||
<a-card title="设备数据">
|
||||
<a-row :gutter="10">
|
||||
<a-col :span="4">
|
||||
<span>设备总数:{{ equipmentData.totalNum }}台</span>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<span>闲置设备总数:{{ equipmentData.idleNum }}台</span>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<span>已达报废年限设备总数:{{ equipmentData.scrapNum }}台</span>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false">
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="equipmentId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
:customRow="customRow"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 1200 }"
|
||||
class="sys-org-table"
|
||||
:striped="true"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@update="handleStatus"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
{{ record.createTime }}
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'useYear'">
|
||||
<span v-if="record.factoryDate">{{ dayjs().diff(dayjs(record.factoryDate), "year") }}年</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'canUseYear'">
|
||||
<span v-if="record.scrapDate">{{ dayjs(record.scrapDate).diff(dayjs(), "year") + 1 }}年</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
{{ record.createTime }}
|
||||
</template>
|
||||
<template v-if="column.key === 'inProject'">
|
||||
<div>
|
||||
<p v-for="(item, index) in record.projectList" :key="index" style="line-height: 1.5">
|
||||
{{ item.projectName }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag v-if="record.status === 0" color="green">闲置</a-tag>
|
||||
<a-tag v-if="record.status === 1" color="red">报废</a-tag>
|
||||
<a-tag v-if="record.status === 2" color="purple">注销</a-tag>
|
||||
<a-tag v-if="record.status === 3" color="orange">转卖</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="showProjectList(record)">历史项目</a>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="openEdit(record)">一机一档</a>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="showQr(record)">设备名片</a>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag v-if="record.status === 0" color="green">闲置</a-tag>
|
||||
<a-tag v-if="record.status === 1" color="red">报废</a-tag>
|
||||
<a-tag v-if="record.status === 2" color="purple">注销</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 @click="openEdit(record)">设备名片</a>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
</div>
|
||||
<!-- 编辑弹窗 -->
|
||||
<EquipmentEdit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
<ProjectList v-model:visible="showProject" :data="current" />
|
||||
</div>
|
||||
<!-- 编辑弹窗 -->
|
||||
<EquipmentEdit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { createVNode, ref } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import type { EleProTable } from 'ele-admin-pro';
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { toDateString } from 'ele-admin-pro';
|
||||
import Search from './components/search.vue';
|
||||
import EquipmentEdit from './components/equipment-edit.vue';
|
||||
import {
|
||||
pageTowerEquipment,
|
||||
removeBatchTowerEquipment,
|
||||
updateBatchTowerEquipment
|
||||
} from '@/api/tower/equipment';
|
||||
import {
|
||||
TowerEquipment,
|
||||
TowerEquipmentParam
|
||||
} from '@/api/tower/equipment/model';
|
||||
import { createVNode, reactive, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { toDateString } from "ele-admin-pro";
|
||||
import Search from "./components/search.vue";
|
||||
import EquipmentEdit from "./components/equipment-edit.vue";
|
||||
import {
|
||||
pageTowerEquipment,
|
||||
removeBatchTowerEquipment, towerEquipmentData, towerEquipmentQr,
|
||||
updateBatchTowerEquipment
|
||||
} from "@/api/tower/equipment";
|
||||
import {
|
||||
TowerEquipment,
|
||||
TowerEquipmentParam
|
||||
} from "@/api/tower/equipment/model";
|
||||
import { ApiResult, PageResult } from "@/api";
|
||||
import dayjs from "dayjs";
|
||||
import ProjectList from "@/views/tower/equipment/components/project-list.vue";
|
||||
|
||||
defineProps<{
|
||||
activeKey?: boolean;
|
||||
data?: any;
|
||||
}>();
|
||||
defineProps<{
|
||||
activeKey?: boolean;
|
||||
data?: any;
|
||||
}>();
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
// 表格实例
|
||||
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: '设备状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
customRender: ({ text }) => ['闲置', '报废', '注销', '转卖'][text]
|
||||
},
|
||||
{
|
||||
title: '设备名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: '设备型号',
|
||||
dataIndex: 'model',
|
||||
key: 'model'
|
||||
},
|
||||
{
|
||||
title: '制造厂商',
|
||||
dataIndex: 'manufactor',
|
||||
key: 'manufactor'
|
||||
},
|
||||
{
|
||||
title: '当前位置',
|
||||
dataIndex: 'currentLocation',
|
||||
key: 'currentLocation'
|
||||
},
|
||||
{
|
||||
title: '产权单位(个人)',
|
||||
dataIndex: 'company',
|
||||
key: 'company'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
sorter: true,
|
||||
customRender: ({ text }) => toDateString(text)
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
align: 'center',
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: "设备状态",
|
||||
dataIndex: "status",
|
||||
key: "status",
|
||||
customRender: ({ text }) => ["闲置", "报废", "注销", "转卖", "在用", "停工"][text]
|
||||
},
|
||||
{
|
||||
title: "设备名称",
|
||||
dataIndex: "name",
|
||||
key: "name"
|
||||
},
|
||||
{
|
||||
title: "出厂编号",
|
||||
dataIndex: "factoryNo"
|
||||
},
|
||||
{
|
||||
title: "设备型号",
|
||||
dataIndex: "model",
|
||||
key: "model"
|
||||
},
|
||||
{
|
||||
title: "备案编号",
|
||||
dataIndex: "filingNo"
|
||||
},
|
||||
{
|
||||
title: "制造厂商",
|
||||
dataIndex: "manufactor",
|
||||
key: "manufactor"
|
||||
},
|
||||
{
|
||||
title: "所在项目",
|
||||
key: "inProject"
|
||||
},
|
||||
{
|
||||
title: "产权单位(个人)",
|
||||
dataIndex: "company",
|
||||
key: "company"
|
||||
},
|
||||
{
|
||||
title: "购买日期",
|
||||
dataIndex: "buyDate"
|
||||
},
|
||||
{
|
||||
title: "已使用年份",
|
||||
key: "useYear"
|
||||
},
|
||||
{
|
||||
title: "剩余可使用年份",
|
||||
key: "canUseYear"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 200,
|
||||
align: "center",
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<TowerEquipment[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<TowerEquipment | null>(null);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
let equipmentData = reactive({
|
||||
totalNum: 0,
|
||||
idleNum: 0,
|
||||
scrapNum: 0
|
||||
});
|
||||
const getData = async () => {
|
||||
const res = await towerEquipmentData();
|
||||
for (let key in equipmentData) equipmentData[key] = res[key];
|
||||
};
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
// 表格选中数据
|
||||
const selection = ref<TowerEquipment[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<TowerEquipment | null>(null);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
// 搜索条件
|
||||
if (filters.payMethod) {
|
||||
where.payMethod = filters.payMethod;
|
||||
}
|
||||
if (filters.deliveryType) {
|
||||
where.deliveryType = filters.deliveryType;
|
||||
}
|
||||
if (filters.payStatus) {
|
||||
where.payStatus = filters.payStatus;
|
||||
}
|
||||
if (filters.orderSource) {
|
||||
where.orderSource = filters.orderSource;
|
||||
}
|
||||
where.tenantId = localStorage.getItem("tenantId");
|
||||
where.payStatus = 20;
|
||||
return pageTowerEquipment({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
// 搜索条件
|
||||
if (filters.payMethod) {
|
||||
where.payMethod = filters.payMethod;
|
||||
}
|
||||
if (filters.deliveryType) {
|
||||
where.deliveryType = filters.deliveryType;
|
||||
}
|
||||
if (filters.payStatus) {
|
||||
where.payStatus = filters.payStatus;
|
||||
}
|
||||
if (filters.orderSource) {
|
||||
where.orderSource = filters.orderSource;
|
||||
}
|
||||
where.tenantId = localStorage.getItem('tenantId');
|
||||
where.payStatus = 20;
|
||||
return pageTowerEquipment({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: TowerEquipmentParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
/* 搜索 */
|
||||
const reload = (where?: TowerEquipmentParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
getData();
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: TowerEquipment) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: TowerEquipment) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
|
||||
/* 批量修改 */
|
||||
const handleStatus = (status) => {
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
const data = selection.value.map((d) => {
|
||||
return {
|
||||
equipmentId: d.equipmentId,
|
||||
status
|
||||
};
|
||||
});
|
||||
console.log(data);
|
||||
updateBatchTowerEquipment(data).then((msg) => {
|
||||
message.success(msg);
|
||||
reload();
|
||||
});
|
||||
};
|
||||
const showQr = async (row?: TowerEquipment) => {
|
||||
const res = towerEquipmentQr({ equipmentId: row?.equipmentId })
|
||||
console.log(res)
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要删除选中的记录吗?',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
removeBatchTowerEquipment(selection.value.map((d) => d.equipmentId))
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
const showProject = ref<Boolean>(false)
|
||||
const showProjectList = async (row?: TowerEquipment) => {
|
||||
current.value = row ?? null;
|
||||
showProject.value = true;
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: TowerEquipment) => {
|
||||
/* 批量修改 */
|
||||
const handleStatus = (status) => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
const data = selection.value.map((d) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
}
|
||||
equipmentId: d.equipmentId,
|
||||
status
|
||||
};
|
||||
};
|
||||
});
|
||||
updateBatchTowerEquipment(data).then((msg) => {
|
||||
message.success(msg);
|
||||
reload();
|
||||
});
|
||||
};
|
||||
|
||||
reload();
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定要删除选中的记录吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchTowerEquipment(selection.value.map((d) => d.equipmentId))
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: TowerEquipment) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
reload();
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'TowerEquipmentIndex'
|
||||
};
|
||||
export default {
|
||||
name: "TowerEquipmentIndex"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
p {
|
||||
line-height: 0.8;
|
||||
}
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
p {
|
||||
line-height: 0.8;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.price-edit {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.comments {
|
||||
max-width: 200px;
|
||||
}
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.price-edit {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.comments {
|
||||
max-width: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -44,14 +44,14 @@
|
||||
v-model:value="form.factory"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="产权单位" name="companyId">
|
||||
<DictSelect
|
||||
:placeholder="'请选择产权单位'"
|
||||
v-model:value="form.companyName"
|
||||
:dict-code="'PropertyCompany'"
|
||||
@done="chooseCompanyName"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="产权单位" name="companyId">-->
|
||||
<!-- <DictSelect-->
|
||||
<!-- :placeholder="'请选择产权单位'"-->
|
||||
<!-- v-model:value="form.companyName"-->
|
||||
<!-- :dict-code="'PropertyCompany'"-->
|
||||
<!-- @done="chooseCompanyName"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<a-form-item label="出厂日期" name="factoryDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
@@ -68,6 +68,14 @@
|
||||
v-model:value="form.discardDate"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="检测日期日期" name="checkDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择日期"
|
||||
v-model:value="form.checkDate"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
@@ -222,6 +230,7 @@ const form = reactive<TowerFall>({
|
||||
factory: "",
|
||||
factoryDate: "",
|
||||
discardDate: undefined,
|
||||
checkDate: undefined,
|
||||
file1: "[]",
|
||||
file2: "[]",
|
||||
file3: "[]",
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
console.log(aoa);
|
||||
aoa.slice(1).map((d) => {
|
||||
const array = ['闲置', '报废', '注销', '转卖'];
|
||||
const array = ['闲置', '报废', '注销', '转卖', '在用', '场地'];
|
||||
importData.value.push({
|
||||
status: array.indexOf(d[0]),
|
||||
name: d[1],
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
<template v-if="column.key === 'nickname'">
|
||||
{{ record.nickname }}
|
||||
</template>
|
||||
<template v-if="column.key === 'checkDate'">
|
||||
<span
|
||||
:style="{color: record.checkDate ? (dayjs().diff(dayjs(record.checkDate), 'day') < 30 ? 'red' : 'black') : 'black'}">
|
||||
{{ record.checkDate }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
{{ record.createTime }}
|
||||
</template>
|
||||
@@ -59,252 +64,261 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { createVNode, ref } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import type { EleProTable } from 'ele-admin-pro';
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { toDateString } from 'ele-admin-pro';
|
||||
import Search from './components/search.vue';
|
||||
import FallEdit from './components/fall-edit.vue';
|
||||
import {
|
||||
pageTowerFall,
|
||||
removeBatchTowerFall,
|
||||
updateBatchTowerFall
|
||||
} from '@/api/tower/fall';
|
||||
import { TowerFall, TowerFallParam } from '@/api/tower/fall/model';
|
||||
import { pageCompany } from '@/api/system/company';
|
||||
import { Customer } from '@/api/oa/customer/model';
|
||||
import { Company } from '@/api/system/company/model';
|
||||
import { createVNode, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { toDateString } from "ele-admin-pro";
|
||||
import Search from "./components/search.vue";
|
||||
import FallEdit from "./components/fall-edit.vue";
|
||||
import {
|
||||
pageTowerFall,
|
||||
removeBatchTowerFall,
|
||||
updateBatchTowerFall
|
||||
} from "@/api/tower/fall";
|
||||
import { TowerFall, TowerFallParam } from "@/api/tower/fall/model";
|
||||
import { pageCompany } from "@/api/system/company";
|
||||
import { Customer } from "@/api/oa/customer/model";
|
||||
import { Company } from "@/api/system/company/model";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
defineProps<{
|
||||
activeKey?: boolean;
|
||||
data?: any;
|
||||
}>();
|
||||
defineProps<{
|
||||
activeKey?: boolean;
|
||||
data?: any;
|
||||
}>();
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
// 表格实例
|
||||
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: '设备状态',
|
||||
// dataIndex: 'status',
|
||||
// key: 'status',
|
||||
// customRender: ({ text }) => ['闲置', '报废', '注销', '转卖'][text]
|
||||
// },
|
||||
{
|
||||
title: '防坠器编号',
|
||||
dataIndex: 'code',
|
||||
key: 'code'
|
||||
},
|
||||
{
|
||||
title: '防坠器型号',
|
||||
dataIndex: 'model',
|
||||
key: 'model'
|
||||
},
|
||||
{
|
||||
title: '制造厂商',
|
||||
dataIndex: 'factory',
|
||||
key: 'factory'
|
||||
},
|
||||
{
|
||||
title: '产权单位',
|
||||
dataIndex: 'companyName',
|
||||
key: 'companyName'
|
||||
},
|
||||
{
|
||||
title: '出厂日期',
|
||||
dataIndex: 'factoryDate',
|
||||
key: 'factoryDate'
|
||||
},
|
||||
{
|
||||
title: '报废日期',
|
||||
dataIndex: 'discardDate',
|
||||
key: 'discardDate'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
sorter: true,
|
||||
customRender: ({ text }) => toDateString(text)
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
align: 'center',
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
// {
|
||||
// title: '设备状态',
|
||||
// dataIndex: 'status',
|
||||
// key: 'status',
|
||||
// customRender: ({ text }) => ['闲置', '报废', '注销', '转卖'][text]
|
||||
// },
|
||||
{
|
||||
title: "防坠器编号",
|
||||
dataIndex: "code",
|
||||
key: "code"
|
||||
},
|
||||
{
|
||||
title: "防坠器型号",
|
||||
dataIndex: "model",
|
||||
key: "model"
|
||||
},
|
||||
{
|
||||
title: "制造厂商",
|
||||
dataIndex: "factory",
|
||||
key: "factory"
|
||||
},
|
||||
{
|
||||
title: "产权单位",
|
||||
dataIndex: "companyName",
|
||||
key: "companyName"
|
||||
},
|
||||
{
|
||||
title: "出厂日期",
|
||||
dataIndex: "factoryDate",
|
||||
key: "factoryDate"
|
||||
},
|
||||
{
|
||||
title: "报废日期",
|
||||
dataIndex: "discardDate",
|
||||
key: "discardDate"
|
||||
},
|
||||
{
|
||||
title: "检测日期",
|
||||
dataIndex: "checkDate",
|
||||
key: "checkDate"
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
dataIndex: "createTime",
|
||||
key: "createTime",
|
||||
align: "center",
|
||||
sorter: true,
|
||||
customRender: ({ text }) => toDateString(text)
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 200,
|
||||
align: "center",
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<TowerFall[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<TowerFall | null>(null);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
const companys = ref<Company[] | undefined>();
|
||||
pageCompany({
|
||||
companyTypeMultiple: '产权单位'
|
||||
}).then((res) => {
|
||||
companys.value = res?.list;
|
||||
});
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
// 表格选中数据
|
||||
const selection = ref<TowerFall[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<TowerFall | null>(null);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
const companys = ref<Company[] | undefined>();
|
||||
pageCompany({
|
||||
companyTypeMultiple: "产权单位"
|
||||
}).then((res) => {
|
||||
companys.value = res?.list;
|
||||
});
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
// 搜索条件
|
||||
if (filters.payMethod) {
|
||||
where.payMethod = filters.payMethod;
|
||||
}
|
||||
if (filters.deliveryType) {
|
||||
where.deliveryType = filters.deliveryType;
|
||||
}
|
||||
if (filters.payStatus) {
|
||||
where.payStatus = filters.payStatus;
|
||||
}
|
||||
if (filters.orderSource) {
|
||||
where.orderSource = filters.orderSource;
|
||||
}
|
||||
where.tenantId = localStorage.getItem("tenantId");
|
||||
where.payStatus = 20;
|
||||
return pageTowerFall({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
// 搜索条件
|
||||
if (filters.payMethod) {
|
||||
where.payMethod = filters.payMethod;
|
||||
}
|
||||
if (filters.deliveryType) {
|
||||
where.deliveryType = filters.deliveryType;
|
||||
}
|
||||
if (filters.payStatus) {
|
||||
where.payStatus = filters.payStatus;
|
||||
}
|
||||
if (filters.orderSource) {
|
||||
where.orderSource = filters.orderSource;
|
||||
}
|
||||
where.tenantId = localStorage.getItem('tenantId');
|
||||
where.payStatus = 20;
|
||||
return pageTowerFall({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: TowerFallParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
/* 搜索 */
|
||||
const reload = (where?: TowerFallParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: TowerFall) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
/* 删除单个 */
|
||||
const remove = (row: TowerFall) => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
removeBatchTowerFall([row.id])
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
/* 批量修改 */
|
||||
const handleStatus = (status) => {
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
const data = selection.value.map((d) => {
|
||||
return {
|
||||
fallId: d.id,
|
||||
status
|
||||
};
|
||||
});
|
||||
console.log(data);
|
||||
updateBatchTowerFall(data).then((msg) => {
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: TowerFall) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
/* 删除单个 */
|
||||
const remove = (row: TowerFall) => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchTowerFall([row.id])
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要删除选中的记录吗?',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
removeBatchTowerFall(selection.value.map((d) => d.id))
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: TowerFall) => {
|
||||
};
|
||||
/* 批量修改 */
|
||||
const handleStatus = (status) => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
const data = selection.value.map((d) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
}
|
||||
fallId: d.id,
|
||||
status
|
||||
};
|
||||
};
|
||||
});
|
||||
console.log(data);
|
||||
updateBatchTowerFall(data).then((msg) => {
|
||||
message.success(msg);
|
||||
reload();
|
||||
});
|
||||
};
|
||||
|
||||
reload();
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定要删除选中的记录吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchTowerFall(selection.value.map((d) => d.id))
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: TowerFall) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
reload();
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'TowerFallIndex'
|
||||
};
|
||||
export default {
|
||||
name: "TowerFallIndex"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
p {
|
||||
line-height: 0.8;
|
||||
}
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
p {
|
||||
line-height: 0.8;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.price-edit {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.comments {
|
||||
max-width: 200px;
|
||||
}
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.price-edit {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.comments {
|
||||
max-width: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
373
src/views/tower/finalSettle/components/edit.vue
Normal file
373
src/views/tower/finalSettle/components/edit.vue
Normal file
@@ -0,0 +1,373 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="'90%'"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:maskClosable="false"
|
||||
:maxable="maxable"
|
||||
:title="isUpdate ? '编辑结算书' : '添加结算书'"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
@ok="save"
|
||||
>
|
||||
<a-form
|
||||
:label-col="{ md: { span: 4 }, sm: { span: 4 }, xs: { span: 4 } }"
|
||||
:label-align="'left'"
|
||||
:wrapper-col="{ md: { span: 24 }, sm: { span: 20 }, xs: { span: 24 } }"
|
||||
>
|
||||
<a-card title="填报人信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<a-form-item label="填报人">
|
||||
<a-input disabled v-model:value="loginUser.username" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<a-form-item label="填报时间">
|
||||
<a-input disabled v-model:value="now" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-card title="合同信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="合同编号" v-bind="validateInfos.contractId">
|
||||
<TowerContractSelectModel
|
||||
:placeholder="`请选择合同`"
|
||||
v-model:value="form.contractNumber"
|
||||
@done="chooseContract"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="承租单位">
|
||||
<p style="margin: 0">{{ form.customerName }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="累计开票金额">
|
||||
<p style="margin: 0">{{ form.totalInvoicingAmount }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="签订日期">
|
||||
<p style="margin: 0">{{ form.signDate }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="租赁单位">
|
||||
<p style="margin: 0">{{ form.companyName }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="结算总金额">
|
||||
<p style="margin: 0">{{ form.totalSettleAmount }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="项目名称">
|
||||
<p style="margin: 0">{{ form.projectName }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="累计收款金额">
|
||||
<p style="margin: 0">{{ form.totalIncomeAmount }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-card title="结算信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="结算单位" v-bind="validateInfos.settleCompanyId">
|
||||
<SelectCompany
|
||||
:placeholder="`请选择结算单位`"
|
||||
v-model:value="form.settleCompanyName"
|
||||
@done="chooseCompany"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="登记人" v-bind="validateInfos.signName">
|
||||
<UserChoose @select="selectSignName" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="登记日期" v-bind="validateInfos.signDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择登记日期"
|
||||
v-model:value="form.signDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item label="备注" :label-col="{ md: { span: 1 }, sm: { span: 1 }, xs: { span: 1 } }">
|
||||
<a-input v-model:value="form.remark" placeholder="请输入备注说明" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="附件" name="parentId">-->
|
||||
<!-- <a-upload-->
|
||||
<!-- v-model:file-list="fileList"-->
|
||||
<!-- name="file"-->
|
||||
<!-- action="https://file.wsdns.cn/api/file/image"-->
|
||||
<!-- :headers="{ Authorization: token }"-->
|
||||
<!-- @change="onFile"-->
|
||||
<!-- >-->
|
||||
<!-- <a-button>-->
|
||||
<!-- <upload-outlined />-->
|
||||
<!-- 上传-->
|
||||
<!-- </a-button>-->
|
||||
<!-- </a-upload>-->
|
||||
<!-- </a-form-item>-->
|
||||
</a-card>
|
||||
<a-card title="缺失物品登记">
|
||||
<a-button @click.native="showSelectItem = true" type="primary" :disabled="!form.contractId">新增
|
||||
</a-button>
|
||||
<Table :data-source="lostList" />
|
||||
</a-card>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
<ele-modal
|
||||
:width="'80%'"
|
||||
:visible="showSelectItem"
|
||||
:maskClosable="false"
|
||||
title="选择配件"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="showSelectItem"
|
||||
@cancel="showSelectItem = false"
|
||||
@ok="showSelectItem = false"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="6">配件名称</a-col>
|
||||
<a-col :span="6">操作</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" class="my-05" v-for="(item, index) in categoryList" :key="index">
|
||||
<a-col :span="6">{{ item.title }}</a-col>
|
||||
<a-col :span="6">
|
||||
<a-button type="link" @click.native="selectItem(item)">选择</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, computed } from "vue";
|
||||
import { Form, message } from "ant-design-vue";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import dayjs from "dayjs";
|
||||
import { Contract } from "@/api/tower/contract/model";
|
||||
import Table from "./table.vue";
|
||||
import { Company } from "@/api/system/company/model";
|
||||
import { User } from "@/api/user/model";
|
||||
import { TOKEN_STORE_NAME } from "@/config/setting";
|
||||
import { UploadOutlined } from "@ant-design/icons-vue";
|
||||
import { FinalSettle } from "@/api/tower/finalSettle/model";
|
||||
import { Category } from "@/api/goods/category/model";
|
||||
import { addFinalSettle, updateFinalSettle } from "@/api/tower/finalSettle";
|
||||
import { FinalSettleLost } from "@/api/tower/finalSettleLost/model";
|
||||
import { addBatchFinalSettleLost } from "@/api/tower/finalSettleLost";
|
||||
import { listCategory } from "@/api/goods/category";
|
||||
|
||||
|
||||
const userStore = useUserStore();
|
||||
const token = localStorage.getItem(TOKEN_STORE_NAME);
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
const useForm = Form.useForm;
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: FinalSettle | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
// 是否显示最大化切换按钮
|
||||
const maxable = ref(true);
|
||||
const activeKey = ref(0);
|
||||
|
||||
const categoryList = ref<Category[]>([]);
|
||||
const getCategoryList = async () => {
|
||||
categoryList.value = await listCategory({ parentId: -1 });
|
||||
};
|
||||
|
||||
const showSelectItem = ref(false);
|
||||
const lostList = ref<FinalSettleLost[]>([]);
|
||||
const selectItem = (item: Category) => {
|
||||
lostList.value.push({
|
||||
finalSettleLostId: null,
|
||||
finalSettleId: null,
|
||||
itemId: item.categoryId,
|
||||
amount: null,
|
||||
num: null,
|
||||
itemName: item.title,
|
||||
total: null
|
||||
});
|
||||
showSelectItem.value = false;
|
||||
};
|
||||
|
||||
const chooseContract = (res: Contract) => {
|
||||
form.contractNumber = res.contactNumber;
|
||||
form.contractId = res.contractId;
|
||||
form.companyName = res.companyName;
|
||||
form.customerName = res.customerName;
|
||||
form.signDate = res.signDate;
|
||||
form.projectName = res.projectName;
|
||||
form.totalInvoicingAmount = res.totalInvoicingAmount;
|
||||
form.totalIncomeAmount = res.totalIncomeAmount;
|
||||
};
|
||||
|
||||
const chooseCompany = ({ companyName, companyId }: Company) => {
|
||||
form.settleCompanyId = companyId;
|
||||
form.settleCompanyName = companyName;
|
||||
};
|
||||
|
||||
const selectSignName = ({ nickname }: User) => {
|
||||
form.signName = nickname;
|
||||
};
|
||||
|
||||
const fileList = ref<FileItem[]>([]);
|
||||
|
||||
interface FileItem {
|
||||
uid: string;
|
||||
name?: string;
|
||||
status?: string;
|
||||
response?: Response;
|
||||
thumbUrl?: string;
|
||||
downloadUrl?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface FileInfo {
|
||||
file: FileItem;
|
||||
fileList: FileItem[];
|
||||
}
|
||||
|
||||
const onFile = (info: FileInfo) => {
|
||||
let resFileList = [...info.fileList];
|
||||
fileList.value = resFileList.map((file) => {
|
||||
if (file.response) {
|
||||
file.url = file.response.url;
|
||||
}
|
||||
return file;
|
||||
});
|
||||
form.fileList = JSON.stringify(fileList.value);
|
||||
};
|
||||
|
||||
const form = reactive<FinalSettle>({
|
||||
contractFinalSettleId: null,
|
||||
contractId: null,
|
||||
settleCompanyId: "",
|
||||
fileList: "[]",
|
||||
signName: "",
|
||||
signDate: dayjs().format("YYYY-MM-DD"),
|
||||
remark: "",
|
||||
settleCompanyName: "",
|
||||
contractNumber: "",
|
||||
companyName: "",
|
||||
customerName: "",
|
||||
projectName: "",
|
||||
totalInvoicingAmount: "",
|
||||
totalIncomeAmount: "",
|
||||
totalSettleAmount: ""
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
contractId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择合同",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
settleCompanyId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择结算单位",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
signDate: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择登记日期",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
signName: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择登记人员",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
});
|
||||
const { resetFields, validate, validateInfos } = useForm(form, rules);
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
validate()
|
||||
.then(async () => {
|
||||
loading.value = true;
|
||||
const data = {
|
||||
...form
|
||||
};
|
||||
const saveOrUpdate = isUpdate.value ? updateFinalSettle : addFinalSettle;
|
||||
const res = await saveOrUpdate(data).catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
if (lostList.value.length > 0) {
|
||||
const finalSettleId = res?.data;
|
||||
lostList.value.forEach((item, index) => {
|
||||
lostList.value[index].finalSettleId = finalSettleId;
|
||||
});
|
||||
await addBatchFinalSettleLost(lostList.value);
|
||||
}
|
||||
message.success(res?.message);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
getCategoryList();
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(form, props.data);
|
||||
isUpdate.value = true;
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
148
src/views/tower/finalSettle/components/info.vue
Normal file
148
src/views/tower/finalSettle/components/info.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="75%"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:title="'合同详情'"
|
||||
:maxable="true"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
:footer="null"
|
||||
>
|
||||
<a-form
|
||||
:label-col="{ md: { span: 4 }, sm: { span: 24 } }"
|
||||
:wrapper-col="{ md: { span: 19 }, sm: { span: 24 } }"
|
||||
>
|
||||
<div class="base-form" style="margin-bottom: 20px">
|
||||
<a-descriptions bordered>
|
||||
<a-descriptions-item label="合同名称">
|
||||
{{ customer.customerName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="社会统一信用代码">
|
||||
{{ customer.customerCode }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="跟进状态">
|
||||
<div color="blue" v-for="(d, index) in progress" :key="index">
|
||||
<span v-if="d.value == customer.progress">{{ d.label }}</span>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系人">
|
||||
{{ customer.customerContacts }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系电话">
|
||||
{{ customer.customerMobile }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="座机电话">
|
||||
{{ customer.customerPhone }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="合同类型">
|
||||
<div color="blue" v-for="(d, index) in customerType" :key="index">
|
||||
<span v-if="d.value == customer.customerType">{{ d.value }}</span>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系地址">
|
||||
{{ customer.customerAddress }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="备注">
|
||||
{{ customer.comments }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<!-- <a-descriptions-->
|
||||
<!-- title="其他信息"-->
|
||||
<!-- :column="1"-->
|
||||
<!-- bordered-->
|
||||
<!-- style="margin-top: 30px"-->
|
||||
<!-- >-->
|
||||
<!-- <a-descriptions-item label="相关项目">-->
|
||||
<!-- {{ customer.comments }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import { assignObject } from 'ele-admin-pro';
|
||||
import type { Customer } from '@/api/oa/customer/model';
|
||||
import { FILE_SERVER } from '@/config/setting';
|
||||
import { getDictionaryOptions } from '@/utils/common';
|
||||
|
||||
const useForm = Form.useForm;
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Customer | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done'): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 用户信息
|
||||
const customer = reactive<Customer>({
|
||||
customerCode: '',
|
||||
customerName: '',
|
||||
customerType: undefined,
|
||||
customerMobile: '',
|
||||
customerAvatar: '',
|
||||
customerPhone: '',
|
||||
customerContacts: '',
|
||||
customerAddress: '',
|
||||
comments: '',
|
||||
progress: '',
|
||||
status: '0',
|
||||
sortNumber: 100,
|
||||
customerId: 0
|
||||
});
|
||||
|
||||
// 请求状态
|
||||
const loading = ref(true);
|
||||
|
||||
const { resetFields } = useForm(customer);
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
|
||||
/* 打开外部链接 */
|
||||
// const openUrl = (record) => {
|
||||
// window.open(record.panel);
|
||||
// };
|
||||
|
||||
/* 获取字典数据 */
|
||||
const customerType = getDictionaryOptions('customerType');
|
||||
const progress = getDictionaryOptions('customerFollowStatus');
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(customer, props.data);
|
||||
}
|
||||
} else {
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style lang="less">
|
||||
.tab-pane {
|
||||
min-height: 100px;
|
||||
}
|
||||
.card-head {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
205
src/views/tower/finalSettle/components/search.vue
Normal file
205
src/views/tower/finalSettle/components/search.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<a-space :size="10" style="flex-wrap: wrap">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
<span>新增</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
v-if="selection.length > 0"
|
||||
@click="removeBatch"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
<span>批量删除</span>
|
||||
</a-button>
|
||||
<!-- <a-button @click="batchMove" v-if="selection.length > 0">-->
|
||||
<!-- <template #icon>-->
|
||||
<!-- <UserSwitchOutlined />-->
|
||||
<!-- </template>-->
|
||||
<!-- 批量转移-->
|
||||
<!-- </a-button>-->
|
||||
<a-input-search
|
||||
allow-clear
|
||||
placeholder="请输入关键词"
|
||||
v-model:value="searchText"
|
||||
@pressEnter="search"
|
||||
@search="search"
|
||||
/>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
PlusOutlined,
|
||||
DeleteOutlined,
|
||||
UploadOutlined,
|
||||
DownloadOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import useSearch from '@/utils/use-search';
|
||||
import type { CustomerParam } from '@/api/oa/customer/model';
|
||||
import { ref, watch } from 'vue';
|
||||
import { utils, read } from 'xlsx';
|
||||
// import { assignObject } from 'ele-admin-pro';
|
||||
import { message } from 'ant-design-vue/es';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
// 选中的角色
|
||||
selection?: [];
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search', where?: CustomerParam): void;
|
||||
(e: 'add'): void;
|
||||
(e: 'remove'): void;
|
||||
(e: 'batchMove'): void;
|
||||
}>();
|
||||
|
||||
// 表单数据
|
||||
const { where } = useSearch<CustomerParam>({
|
||||
name: '',
|
||||
creditCode: '',
|
||||
keywords: '',
|
||||
userId: undefined
|
||||
});
|
||||
// 下来选项
|
||||
// 搜索内容
|
||||
const searchText = ref('');
|
||||
|
||||
/* 搜索 */
|
||||
const search = () => {
|
||||
where.keywords = searchText.value;
|
||||
emit('search', where);
|
||||
};
|
||||
|
||||
// 新增
|
||||
const add = () => {
|
||||
emit('add');
|
||||
};
|
||||
|
||||
// 导入数据的列
|
||||
const importTitle = ref<string[]>(['A', 'B', 'C', 'D', 'E', 'F', 'G']);
|
||||
// 导入的数据
|
||||
const importData = ref<Record<string, any>[]>([]);
|
||||
// 导入数据二维数组形式
|
||||
const importDataAoa = ref<(string | number)[][]>([]);
|
||||
|
||||
/* 导入本地 excel 文件 */
|
||||
const importBatch = (file: File) => {
|
||||
if (
|
||||
![
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
].includes(file.type)
|
||||
) {
|
||||
message.error('只能选择 excel 文件');
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
message.error('大小不能超过 20MB');
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target?.result as any);
|
||||
const workbook = read(data, { type: 'array' });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
// 生成表格需要的数据
|
||||
let list: Record<string, any>[] = [];
|
||||
let maxCols = 0;
|
||||
let title: string[] = [];
|
||||
aoa.forEach((d) => {
|
||||
if (d.length > maxCols) {
|
||||
maxCols = d.length;
|
||||
}
|
||||
const row = {};
|
||||
for (let i = 0; i < d.length; i++) {
|
||||
const key = getCharByIndex(i);
|
||||
row[key] = d[i];
|
||||
row['__colspan__' + key] = 1;
|
||||
row['__rowspan__' + key] = 1;
|
||||
}
|
||||
list.push(row);
|
||||
});
|
||||
for (let i = 0; i < maxCols; i++) {
|
||||
title.push(getCharByIndex(i));
|
||||
}
|
||||
importTitle.value = title;
|
||||
importData.value = list;
|
||||
importDataAoa.value = aoa;
|
||||
};
|
||||
console.log(importData.value);
|
||||
console.log(importDataAoa.value);
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
};
|
||||
/* 生成Excel列字母序号 */
|
||||
const getCharByIndex = (index: number) => {
|
||||
const chars = [
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z'
|
||||
];
|
||||
if (index < chars.length) {
|
||||
return chars[index];
|
||||
}
|
||||
const n = parseInt(String(index / chars.length));
|
||||
const m = index % chars.length;
|
||||
return chars[n] + chars[m];
|
||||
};
|
||||
|
||||
// 转移
|
||||
// const batchMove = () => {
|
||||
// emit('batchMove');
|
||||
// };
|
||||
|
||||
// 批量删除
|
||||
const removeBatch = () => {
|
||||
emit('remove');
|
||||
};
|
||||
|
||||
const onClear = () => {
|
||||
where.userId = undefined;
|
||||
search();
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.selection,
|
||||
() => {}
|
||||
);
|
||||
</script>
|
||||
95
src/views/tower/finalSettle/components/table.vue
Normal file
95
src/views/tower/finalSettle/components/table.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<a-table ref="tableRef"
|
||||
row-key="contractSettleId" :dataSource="dataList" :columns="columns">
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'amount'">
|
||||
<a-input v-model:value="record.amount" type="number" @change="changeItem($event, index)">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'num'">
|
||||
<a-input v-model:value="record.num" type="number" @change="changeItem($event, index)">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<div class="flex justify-center items-center">
|
||||
<close-circle-outlined style="font-size: 1.5rem; color: pink;cursor: pointer"
|
||||
@click.native="del(index)" />
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { ColumnItem } from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import {
|
||||
CloseCircleOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import { FinalSettleLost } from "@/api/tower/finalSettleLost/model";
|
||||
|
||||
const props = defineProps<{
|
||||
dataSource: FinalSettleLost[]
|
||||
}>();
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
const emits = defineEmits(["total"]);
|
||||
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: "序号",
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 1)
|
||||
},
|
||||
{
|
||||
title: "配件名称",
|
||||
dataIndex: "itemName"
|
||||
},
|
||||
{
|
||||
title: "赔偿单价",
|
||||
dataIndex: "amount",
|
||||
key: "amount"
|
||||
},
|
||||
{
|
||||
title: "赔偿数量",
|
||||
dataIndex: "num",
|
||||
key: "num"
|
||||
},
|
||||
{
|
||||
title: "赔偿总额",
|
||||
dataIndex: "total",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "action",
|
||||
key: "action"
|
||||
}
|
||||
]);
|
||||
|
||||
const changeItem = (value, index) => {
|
||||
dataList.value[index].total = parseFloat(dataList.value[index].amount) * parseInt(dataList.value[index].num);
|
||||
};
|
||||
|
||||
const dataList = ref<FinalSettleLost[]>([]);
|
||||
|
||||
const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
defineExpose({ dataList });
|
||||
</script>
|
||||
269
src/views/tower/finalSettle/index.vue
Normal file
269
src/views/tower/finalSettle/index.vue
Normal file
@@ -0,0 +1,269 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="contractFinalSettleId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 800 }"
|
||||
class="sys-org-table"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@batchMove="openMove"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<span>{{ INCOME_STATUS_LIST[record.status] }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
<a-tooltip :title="`${toDateString(record.createTime)}`">
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="确定要删除此记录吗?"
|
||||
@confirm="remove(record)"
|
||||
>
|
||||
<a class="ele-text-danger">删除</a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<Edit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
<!-- 合同详情弹窗 -->
|
||||
<Info v-model:visible="showInfo" :data="current" @done="reload" />
|
||||
<!-- 批量转移弹窗 -->
|
||||
<!-- <CustomerMove v-model:visible="showMove" :data="selection" @done="batchMove" />-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, createVNode, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import {
|
||||
ExclamationCircleOutlined,
|
||||
UserOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { toDateString } from "ele-admin-pro";
|
||||
import Search from "./components/search.vue";
|
||||
import Edit from "./components/edit.vue";
|
||||
import Info from "./components/info.vue";
|
||||
import { timeAgo } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { FinalSettle, FinalSettleParam } from "@/api/tower/finalSettle/model";
|
||||
import { pageFinalSettle, removeBatchFinalSettle, removeFinalSettle } from "@/api/tower/finalSettle";
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<FinalSettle[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<FinalSettle | null>(null);
|
||||
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 是否显示批量移动弹窗
|
||||
const showMove = ref(false);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
if (filters) {
|
||||
where.status = filters.status;
|
||||
}
|
||||
return pageFinalSettle({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: "合同编号",
|
||||
dataIndex: "contactNumber"
|
||||
},
|
||||
{
|
||||
title: "项目名称",
|
||||
dataIndex: "projectName"
|
||||
},
|
||||
{
|
||||
title: "承租单位",
|
||||
dataIndex: "customerName"
|
||||
},
|
||||
{
|
||||
title: "结算单位",
|
||||
dataIndex: "companyName"
|
||||
},
|
||||
{
|
||||
title: "结算日期",
|
||||
dataIndex: "signDate"
|
||||
},
|
||||
{
|
||||
title: "结算总金额",
|
||||
dataIndex: "totalSettleAmount"
|
||||
},
|
||||
{
|
||||
title: "登记人员",
|
||||
dataIndex: "signName"
|
||||
},
|
||||
{
|
||||
title: "操作日期",
|
||||
dataIndex: "createtime"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 200,
|
||||
align: "center",
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: FinalSettleParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: FinalSettle) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
|
||||
const showSettle = ref<Boolean>(false);
|
||||
const openSettle = (row?: FinalSettle) => {
|
||||
current.value = row ?? null;
|
||||
showSettle.value = true;
|
||||
};
|
||||
|
||||
/* 打开批量移动弹窗 */
|
||||
const openMove = () => {
|
||||
showMove.value = true;
|
||||
};
|
||||
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row?: FinalSettle) => {
|
||||
current.value = row ?? null;
|
||||
showInfo.value = true;
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: FinalSettle) => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeFinalSettle(row.contractFinalSettleId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量转移 */
|
||||
const batchMove = (userId) => {
|
||||
console.log(userId, "批量转移0000");
|
||||
console.log(selection.value);
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定要删除选中的记录吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchFinalSettle(
|
||||
selection.value.map((d) => {
|
||||
if (loginUser.value.userId === d.userId) {
|
||||
return d.contractFinalSettleId;
|
||||
}
|
||||
})
|
||||
)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Accessory"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
441
src/views/tower/income/components/edit.vue
Normal file
441
src/views/tower/income/components/edit.vue
Normal file
@@ -0,0 +1,441 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="'90%'"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:maskClosable="false"
|
||||
:maxable="maxable"
|
||||
:title="isUpdate ? '编辑收款' : '添加收款'"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
@ok="save"
|
||||
>
|
||||
<a-form
|
||||
:label-col="{ md: { span: 4 }, sm: { span: 4 }, xs: { span: 4 } }"
|
||||
:label-align="'left'"
|
||||
:wrapper-col="{ md: { span: 24 }, sm: { span: 20 }, xs: { span: 24 } }"
|
||||
>
|
||||
<a-card title="填报人信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<a-form-item label="填报人">
|
||||
<a-input disabled v-model:value="loginUser.username" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<a-form-item label="填报时间">
|
||||
<a-input disabled v-model:value="now" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-card title="合同信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="合同编号" v-bind="validateInfos.contractId">
|
||||
<TowerContractSelectModel
|
||||
:placeholder="`请选择合同`"
|
||||
v-model:value="form.contractNumber"
|
||||
@done="chooseContract"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="承租单位">
|
||||
<p style="margin: 0">{{ form.customerName }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="累计开票金额">
|
||||
<p style="margin: 0">{{ form.totalInvoicingAmount }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="签订日期">
|
||||
<p style="margin: 0">{{ form.signDate }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="租赁单位">
|
||||
<p style="margin: 0">{{ form.companyName }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="项目名称">
|
||||
<p style="margin: 0">{{ form.projectName }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="累计收款">
|
||||
<p style="margin: 0">{{ form.totalIncomeAmount }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-card title="收款信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="收款单号">
|
||||
<a-input v-model:value="form.incomeNo" placeholder="请输入收款单号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="收款金额" v-bind="validateInfos.amount">
|
||||
<a-input v-model:value="form.amount" placeholder="请输入收款金额" type="number">
|
||||
<template #addonAfter>元</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="预计收款日期">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择预计收款日期"
|
||||
v-model:value="form.expectIncomeDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="收款日期" v-bind="validateInfos.incomeDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择收款日期"
|
||||
v-model:value="form.incomeDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="收款类型">
|
||||
<a-select placeholder="请选择收款类型" style="width: 250px" size="small"
|
||||
v-model:value="form.incomeType">
|
||||
<a-select-option value="直租">直租</a-select-option>
|
||||
<a-select-option value="转租">转租</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="预计收款金额">
|
||||
<a-input v-model:value="form.expectIncomeAmount" placeholder="请输入预计收款金额" type="number">
|
||||
<template #addonAfter>元</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="收款单位" v-bind="validateInfos.incomeCompanyId">
|
||||
<SelectCustomer
|
||||
:placeholder="`请选择收款单位`"
|
||||
v-model:value="form.incomeCompanyName"
|
||||
@done="chooseIncomeCompany"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="付款单位">
|
||||
<SelectCompany
|
||||
:placeholder="`请选择付款单位`"
|
||||
v-model:value="form.payCompanyName"
|
||||
@done="choosePayCompany"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="登记人" v-bind="validateInfos.signName">
|
||||
<UserChoose @select="selectSignName" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item label="收款方式" :label-col="{ md: { span: 1 }, sm: { span: 1 }, xs: { span: 1 } }">
|
||||
<DictSelect
|
||||
dict-code="ContractIncomeMethod"
|
||||
placeholder="请选择收款方式"
|
||||
v-model:value="form.incomeMethod"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="发票号" :label-col="{ md: { span: 1 }, sm: { span: 1 }, xs: { span: 1 } }">
|
||||
<a-input v-model:value="form.invoicingNo" placeholder="请输入发票号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="备注" :label-col="{ md: { span: 1 }, sm: { span: 1 }, xs: { span: 1 } }">
|
||||
<a-input v-model:value="form.remark" placeholder="请输入备注说明" />
|
||||
</a-form-item>
|
||||
<a-form-item label="附件" name="parentId">
|
||||
<a-upload
|
||||
v-model:file-list="fileList"
|
||||
name="file"
|
||||
action="https://file.wsdns.cn/api/file/image"
|
||||
:headers="{ Authorization: token }"
|
||||
@change="onFile"
|
||||
>
|
||||
<a-button>
|
||||
<upload-outlined />
|
||||
上传
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</a-form-item>
|
||||
</a-card>
|
||||
<a-card title="费用设备分摊">
|
||||
<a-button @click.native="showSelectSettle = true" type="primary" :disabled="!form.contractId">新增
|
||||
</a-button>
|
||||
<Table :data-source="settleList" />
|
||||
</a-card>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
<ele-modal
|
||||
:width="'80%'"
|
||||
:visible="showSelectSettle"
|
||||
:maskClosable="false"
|
||||
title="选择设备"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="showSelectSettle"
|
||||
@cancel="showSelectSettle = false"
|
||||
@ok="showSelectSettle = false"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="6">设备名称</a-col>
|
||||
<a-col :span="6">设备型号</a-col>
|
||||
<a-col :span="6">租金</a-col>
|
||||
<a-col :span="6">操作</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" class="my-05" v-for="(item, index) in contractSettleList" :key="index">
|
||||
<a-col :span="6">{{ item.equipmentName }}</a-col>
|
||||
<a-col :span="6">{{ item.equipmentModel }}</a-col>
|
||||
<a-col :span="6">{{ item.rentAmount }}</a-col>
|
||||
<a-col :span="6">
|
||||
<a-button type="link" @click.native="selectSettle(item)">选择</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, computed } from "vue";
|
||||
import { Form, message } from "ant-design-vue";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import dayjs from "dayjs";
|
||||
import { Contract } from "@/api/tower/contract/model";
|
||||
import Table from "./table.vue";
|
||||
import { Company } from "@/api/system/company/model";
|
||||
import { User } from "@/api/user/model";
|
||||
import { TOKEN_STORE_NAME } from "@/config/setting";
|
||||
import { UploadOutlined } from "@ant-design/icons-vue";
|
||||
import { addIncome, updateIncome } from "@/api/tower/income";
|
||||
import { Income } from "@/api/tower/income/model";
|
||||
import { IncomeEquipment } from "@/api/tower/incomeEquipment/model";
|
||||
import { addBatchIncomeEquipment } from "@/api/tower/incomeEquipment";
|
||||
import { ContractSettleEquipment } from "@/api/tower/contractSettle/equipment/model";
|
||||
import { listContractEquipment } from "@/api/tower/contractEquipment";
|
||||
import { ContractEquipment } from "@/api/tower/contractEquipment/model";
|
||||
import { Customer } from "@/api/oa/customer/model";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const token = localStorage.getItem(TOKEN_STORE_NAME);
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
const useForm = Form.useForm;
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Income | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
// 是否显示最大化切换按钮
|
||||
const maxable = ref(true);
|
||||
const activeKey = ref(0);
|
||||
|
||||
const contractSettleList = ref<ContractEquipment[]>([]);
|
||||
const getContractSettleList = async contractId => {
|
||||
contractSettleList.value = await listContractEquipment({ contractId });
|
||||
};
|
||||
|
||||
const showSelectSettle = ref(false);
|
||||
const settleList = ref<IncomeEquipment[]>([]);
|
||||
const selectSettle = (item: ContractEquipment) => {
|
||||
settleList.value.push({
|
||||
incomeEquipmentId: null,
|
||||
incomeId: null,
|
||||
equipmentId: item.equipmentId,
|
||||
equipmentName: item.equipmentName,
|
||||
equipmentModel: item.equipmentModel,
|
||||
factoryNo: item.factoryNo,
|
||||
equipmentNo: item.equipmentNo,
|
||||
filingNo: item.filingNo,
|
||||
rentAmount: item.rentAmount,
|
||||
shareAmount: null
|
||||
});
|
||||
showSelectSettle.value = false;
|
||||
};
|
||||
|
||||
const chooseContract = (res: Contract) => {
|
||||
form.contractNumber = res.contactNumber;
|
||||
form.contractId = res.contractId;
|
||||
form.companyName = res.companyName;
|
||||
form.customerName = res.customerName;
|
||||
form.signDate = res.signDate;
|
||||
form.projectName = res.projectName;
|
||||
form.totalInvoicingAmount = res.totalInvoicingAmount;
|
||||
form.totalIncomeAmount = res.totalIncomeAmount;
|
||||
getContractSettleList(res.contractId);
|
||||
};
|
||||
|
||||
const choosePayCompany = ({ companyName, companyId }: Company) => {
|
||||
form.payCompanyId = companyId;
|
||||
form.payCompanyName = companyName;
|
||||
};
|
||||
|
||||
const chooseIncomeCompany = ({ customerId, name }: Customer) => {
|
||||
form.incomeCompanyId = customerId;
|
||||
form.incomeCompanyName = name;
|
||||
};
|
||||
|
||||
const selectSignName = ({ nickname }: User) => {
|
||||
form.signName = nickname;
|
||||
};
|
||||
|
||||
const fileList = ref<FileItem[]>([]);
|
||||
|
||||
interface FileItem {
|
||||
uid: string;
|
||||
name?: string;
|
||||
status?: string;
|
||||
response?: Response;
|
||||
thumbUrl?: string;
|
||||
downloadUrl?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface FileInfo {
|
||||
file: FileItem;
|
||||
fileList: FileItem[];
|
||||
}
|
||||
|
||||
const onFile = (info: FileInfo) => {
|
||||
let resFileList = [...info.fileList];
|
||||
fileList.value = resFileList.map((file) => {
|
||||
if (file.response) {
|
||||
file.url = file.response.url;
|
||||
}
|
||||
return file;
|
||||
});
|
||||
form.fileList = JSON.stringify(fileList.value);
|
||||
};
|
||||
|
||||
const form = reactive<Income>({
|
||||
incomeId: "",
|
||||
contractId: "",
|
||||
contractNumber: "",
|
||||
signDate: "",
|
||||
projectName: "",
|
||||
customerName: "",
|
||||
companyName: "",
|
||||
incomeNo: `I-` + dayjs().format("YYYY-MM-DD"),
|
||||
incomeCompanyName: "",
|
||||
incomeCompanyId: "",
|
||||
payCompanyName: "",
|
||||
payCompanyId: "",
|
||||
incomeDate: "",
|
||||
amount: "",
|
||||
totalIncomeAmount: "",
|
||||
totalInvoicingAmount: "",
|
||||
fileList: "[]",
|
||||
remark: "",
|
||||
userId: loginUser.value.userId,
|
||||
signName: loginUser.value.username
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
contractId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择合同",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
amount: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入收款金额",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
incomeDate: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入收款日期",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
incomeCompanyId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择收款单位",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
signName: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择登记人员",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
|
||||
});
|
||||
const { resetFields, validate, validateInfos } = useForm(form, rules);
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
validate()
|
||||
.then(async () => {
|
||||
loading.value = true;
|
||||
const data = {
|
||||
...form
|
||||
};
|
||||
const saveOrUpdate = isUpdate.value ? updateIncome : addIncome;
|
||||
const res = await saveOrUpdate(data).catch((e) => {
|
||||
message.error(e.message);
|
||||
});
|
||||
loading.value = false;
|
||||
if (settleList.value.length > 0) {
|
||||
const incomeId = res?.data;
|
||||
settleList.value.forEach((item, index) => {
|
||||
settleList.value[index].incomeId = incomeId;
|
||||
});
|
||||
await addBatchIncomeEquipment(settleList.value);
|
||||
}
|
||||
message.success(res?.message);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(form, props.data);
|
||||
isUpdate.value = true;
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
148
src/views/tower/income/components/info.vue
Normal file
148
src/views/tower/income/components/info.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="75%"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:title="'合同详情'"
|
||||
:maxable="true"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
:footer="null"
|
||||
>
|
||||
<a-form
|
||||
:label-col="{ md: { span: 4 }, sm: { span: 24 } }"
|
||||
:wrapper-col="{ md: { span: 19 }, sm: { span: 24 } }"
|
||||
>
|
||||
<div class="base-form" style="margin-bottom: 20px">
|
||||
<a-descriptions bordered>
|
||||
<a-descriptions-item label="合同名称">
|
||||
{{ customer.customerName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="社会统一信用代码">
|
||||
{{ customer.customerCode }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="跟进状态">
|
||||
<div color="blue" v-for="(d, index) in progress" :key="index">
|
||||
<span v-if="d.value == customer.progress">{{ d.label }}</span>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系人">
|
||||
{{ customer.customerContacts }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系电话">
|
||||
{{ customer.customerMobile }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="座机电话">
|
||||
{{ customer.customerPhone }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="合同类型">
|
||||
<div color="blue" v-for="(d, index) in customerType" :key="index">
|
||||
<span v-if="d.value == customer.customerType">{{ d.value }}</span>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系地址">
|
||||
{{ customer.customerAddress }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="备注">
|
||||
{{ customer.comments }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<!-- <a-descriptions-->
|
||||
<!-- title="其他信息"-->
|
||||
<!-- :column="1"-->
|
||||
<!-- bordered-->
|
||||
<!-- style="margin-top: 30px"-->
|
||||
<!-- >-->
|
||||
<!-- <a-descriptions-item label="相关项目">-->
|
||||
<!-- {{ customer.comments }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import { assignObject } from 'ele-admin-pro';
|
||||
import type { Customer } from '@/api/oa/customer/model';
|
||||
import { FILE_SERVER } from '@/config/setting';
|
||||
import { getDictionaryOptions } from '@/utils/common';
|
||||
|
||||
const useForm = Form.useForm;
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Customer | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done'): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 用户信息
|
||||
const customer = reactive<Customer>({
|
||||
customerCode: '',
|
||||
customerName: '',
|
||||
customerType: undefined,
|
||||
customerMobile: '',
|
||||
customerAvatar: '',
|
||||
customerPhone: '',
|
||||
customerContacts: '',
|
||||
customerAddress: '',
|
||||
comments: '',
|
||||
progress: '',
|
||||
status: '0',
|
||||
sortNumber: 100,
|
||||
customerId: 0
|
||||
});
|
||||
|
||||
// 请求状态
|
||||
const loading = ref(true);
|
||||
|
||||
const { resetFields } = useForm(customer);
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
|
||||
/* 打开外部链接 */
|
||||
// const openUrl = (record) => {
|
||||
// window.open(record.panel);
|
||||
// };
|
||||
|
||||
/* 获取字典数据 */
|
||||
const customerType = getDictionaryOptions('customerType');
|
||||
const progress = getDictionaryOptions('customerFollowStatus');
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(customer, props.data);
|
||||
}
|
||||
} else {
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style lang="less">
|
||||
.tab-pane {
|
||||
min-height: 100px;
|
||||
}
|
||||
.card-head {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
205
src/views/tower/income/components/search.vue
Normal file
205
src/views/tower/income/components/search.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<a-space :size="10" style="flex-wrap: wrap">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
<span>新增</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
v-if="selection.length > 0"
|
||||
@click="removeBatch"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
<span>批量删除</span>
|
||||
</a-button>
|
||||
<!-- <a-button @click="batchMove" v-if="selection.length > 0">-->
|
||||
<!-- <template #icon>-->
|
||||
<!-- <UserSwitchOutlined />-->
|
||||
<!-- </template>-->
|
||||
<!-- 批量转移-->
|
||||
<!-- </a-button>-->
|
||||
<a-input-search
|
||||
allow-clear
|
||||
placeholder="请输入关键词"
|
||||
v-model:value="searchText"
|
||||
@pressEnter="search"
|
||||
@search="search"
|
||||
/>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
PlusOutlined,
|
||||
DeleteOutlined,
|
||||
UploadOutlined,
|
||||
DownloadOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import useSearch from '@/utils/use-search';
|
||||
import type { CustomerParam } from '@/api/oa/customer/model';
|
||||
import { ref, watch } from 'vue';
|
||||
import { utils, read } from 'xlsx';
|
||||
// import { assignObject } from 'ele-admin-pro';
|
||||
import { message } from 'ant-design-vue/es';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
// 选中的角色
|
||||
selection?: [];
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search', where?: CustomerParam): void;
|
||||
(e: 'add'): void;
|
||||
(e: 'remove'): void;
|
||||
(e: 'batchMove'): void;
|
||||
}>();
|
||||
|
||||
// 表单数据
|
||||
const { where } = useSearch<CustomerParam>({
|
||||
name: '',
|
||||
creditCode: '',
|
||||
keywords: '',
|
||||
userId: undefined
|
||||
});
|
||||
// 下来选项
|
||||
// 搜索内容
|
||||
const searchText = ref('');
|
||||
|
||||
/* 搜索 */
|
||||
const search = () => {
|
||||
where.keywords = searchText.value;
|
||||
emit('search', where);
|
||||
};
|
||||
|
||||
// 新增
|
||||
const add = () => {
|
||||
emit('add');
|
||||
};
|
||||
|
||||
// 导入数据的列
|
||||
const importTitle = ref<string[]>(['A', 'B', 'C', 'D', 'E', 'F', 'G']);
|
||||
// 导入的数据
|
||||
const importData = ref<Record<string, any>[]>([]);
|
||||
// 导入数据二维数组形式
|
||||
const importDataAoa = ref<(string | number)[][]>([]);
|
||||
|
||||
/* 导入本地 excel 文件 */
|
||||
const importBatch = (file: File) => {
|
||||
if (
|
||||
![
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
].includes(file.type)
|
||||
) {
|
||||
message.error('只能选择 excel 文件');
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
message.error('大小不能超过 20MB');
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target?.result as any);
|
||||
const workbook = read(data, { type: 'array' });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
// 生成表格需要的数据
|
||||
let list: Record<string, any>[] = [];
|
||||
let maxCols = 0;
|
||||
let title: string[] = [];
|
||||
aoa.forEach((d) => {
|
||||
if (d.length > maxCols) {
|
||||
maxCols = d.length;
|
||||
}
|
||||
const row = {};
|
||||
for (let i = 0; i < d.length; i++) {
|
||||
const key = getCharByIndex(i);
|
||||
row[key] = d[i];
|
||||
row['__colspan__' + key] = 1;
|
||||
row['__rowspan__' + key] = 1;
|
||||
}
|
||||
list.push(row);
|
||||
});
|
||||
for (let i = 0; i < maxCols; i++) {
|
||||
title.push(getCharByIndex(i));
|
||||
}
|
||||
importTitle.value = title;
|
||||
importData.value = list;
|
||||
importDataAoa.value = aoa;
|
||||
};
|
||||
console.log(importData.value);
|
||||
console.log(importDataAoa.value);
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
};
|
||||
/* 生成Excel列字母序号 */
|
||||
const getCharByIndex = (index: number) => {
|
||||
const chars = [
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z'
|
||||
];
|
||||
if (index < chars.length) {
|
||||
return chars[index];
|
||||
}
|
||||
const n = parseInt(String(index / chars.length));
|
||||
const m = index % chars.length;
|
||||
return chars[n] + chars[m];
|
||||
};
|
||||
|
||||
// 转移
|
||||
// const batchMove = () => {
|
||||
// emit('batchMove');
|
||||
// };
|
||||
|
||||
// 批量删除
|
||||
const removeBatch = () => {
|
||||
emit('remove');
|
||||
};
|
||||
|
||||
const onClear = () => {
|
||||
where.userId = undefined;
|
||||
search();
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.selection,
|
||||
() => {}
|
||||
);
|
||||
</script>
|
||||
98
src/views/tower/income/components/table.vue
Normal file
98
src/views/tower/income/components/table.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<a-table ref="tableRef"
|
||||
row-key="contractSettleId" :dataSource="dataList" :columns="columns">
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'shareAmount'">
|
||||
<a-input v-model:value="record.shareAmount" type="number">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<div class="flex justify-center items-center">
|
||||
<close-circle-outlined style="font-size: 1.5rem; color: pink;cursor: pointer"
|
||||
@click.native="del(index)" />
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { ColumnItem } from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import {
|
||||
CloseCircleOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import { InvoicingSettle } from "@/api/tower/invoicingSettle/model";
|
||||
import { IncomeEquipment } from "@/api/tower/incomeEquipment/model";
|
||||
|
||||
const props = defineProps<{
|
||||
dataSource: InvoicingSettle[]
|
||||
}>();
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
const emits = defineEmits(["total"]);
|
||||
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: "序号",
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 1)
|
||||
},
|
||||
{
|
||||
title: "设备名称",
|
||||
dataIndex: "equipmentName"
|
||||
},
|
||||
{
|
||||
title: "设备型号",
|
||||
dataIndex: "equipmentModel"
|
||||
},
|
||||
{
|
||||
title: "出场编号",
|
||||
dataIndex: "factoryNo"
|
||||
},
|
||||
{
|
||||
title: "自编号",
|
||||
dataIndex: "equipmentNo"
|
||||
},
|
||||
{
|
||||
title: "备案编号",
|
||||
dataIndex: "filingNo"
|
||||
},
|
||||
{
|
||||
title: "租金",
|
||||
dataIndex: "rentAmount"
|
||||
},
|
||||
{
|
||||
title: "分摊费用",
|
||||
dataIndex: "shareAmount",
|
||||
key: "shareAmount"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "action",
|
||||
key: "action"
|
||||
}
|
||||
]);
|
||||
|
||||
const dataList = ref<IncomeEquipment[]>([]);
|
||||
|
||||
const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
defineExpose({ dataList });
|
||||
</script>
|
||||
286
src/views/tower/income/index.vue
Normal file
286
src/views/tower/income/index.vue
Normal file
@@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="incomeId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 800 }"
|
||||
class="sys-org-table"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@batchMove="openMove"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<span>{{ INCOME_STATUS_LIST[record.status] }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
<a-tooltip :title="`${toDateString(record.createTime)}`">
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="确定要删除此记录吗?"
|
||||
@confirm="remove(record)"
|
||||
>
|
||||
<a class="ele-text-danger">删除</a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<Edit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
<!-- 合同详情弹窗 -->
|
||||
<Info v-model:visible="showInfo" :data="current" @done="reload" />
|
||||
<!-- 批量转移弹窗 -->
|
||||
<!-- <CustomerMove v-model:visible="showMove" :data="selection" @done="batchMove" />-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, createVNode, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import {
|
||||
ExclamationCircleOutlined,
|
||||
UserOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { toDateString } from "ele-admin-pro";
|
||||
import Search from "./components/search.vue";
|
||||
import Edit from "./components/edit.vue";
|
||||
import Info from "./components/info.vue";
|
||||
import { timeAgo } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { Income, INCOME_STATUS_LIST } from "@/api/tower/income/model";
|
||||
import { pageIncome } from "@/api/tower/income";
|
||||
import { removeBatchIncome, removeIncome } from "@/api/tower/income";
|
||||
import { IncomeParam } from "@/api/tower/income/model";
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<Income[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<Income | null>(null);
|
||||
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 是否显示批量移动弹窗
|
||||
const showMove = ref(false);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
if (filters) {
|
||||
where.status = filters.status;
|
||||
}
|
||||
return pageIncome({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: "incomeId",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: "收款单号",
|
||||
dataIndex: "incomeNo"
|
||||
},
|
||||
{
|
||||
title: "收款状态",
|
||||
dataIndex: "status",
|
||||
key: "status"
|
||||
},
|
||||
{
|
||||
title: "收款日期",
|
||||
dataIndex: "incomeDate"
|
||||
},
|
||||
{
|
||||
title: "合同编号",
|
||||
dataIndex: "contactNumber"
|
||||
},
|
||||
{
|
||||
title: "项目名称",
|
||||
dataIndex: "projectName"
|
||||
},
|
||||
{
|
||||
title: "承租单位",
|
||||
dataIndex: "customerName"
|
||||
},
|
||||
{
|
||||
title: "收款单位",
|
||||
dataIndex: "incomeCompanyName"
|
||||
},
|
||||
{
|
||||
title: "预计收款金额",
|
||||
dataIndex: "expectIncomeAmount"
|
||||
},
|
||||
{
|
||||
title: "收款金额",
|
||||
dataIndex: "amount"
|
||||
},
|
||||
{
|
||||
title: "收款方式",
|
||||
dataIndex: "incomeMethod"
|
||||
},
|
||||
{
|
||||
title: "登记人员",
|
||||
dataIndex: "signName"
|
||||
},
|
||||
{
|
||||
title: "操作日期",
|
||||
dataIndex: "createtime"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 200,
|
||||
align: "center",
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: IncomeParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Income) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
|
||||
const showSettle = ref<Boolean>(false);
|
||||
const openSettle = (row?: Income) => {
|
||||
current.value = row ?? null;
|
||||
showSettle.value = true;
|
||||
};
|
||||
|
||||
/* 打开批量移动弹窗 */
|
||||
const openMove = () => {
|
||||
showMove.value = true;
|
||||
};
|
||||
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row?: Income) => {
|
||||
current.value = row ?? null;
|
||||
showInfo.value = true;
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: Income) => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeIncome(row.incomeId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量转移 */
|
||||
const batchMove = (userId) => {
|
||||
console.log(userId, "批量转移0000");
|
||||
console.log(selection.value);
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定要删除选中的记录吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchIncome(
|
||||
selection.value.map((d) => {
|
||||
return d.incomeId;
|
||||
})
|
||||
)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Accessory"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
243
src/views/tower/installNApartManage/worksheet/index.vue
Normal file
243
src/views/tower/installNApartManage/worksheet/index.vue
Normal file
@@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="worksheetId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 800 }"
|
||||
class="sys-org-table"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@batchMove="openMove"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<span>{{ WORKSHEET_STATUS_LIST[record.status] }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'equipmentType'">
|
||||
<span>{{ WORKSHEET_EQUIPMENT_TYPE[record.equipmentType] }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'workType'">
|
||||
<span>{{ WORKSHEET_WORK_TYPE[record.workType] }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'startUser'">
|
||||
<span>{{ record.startUser ?.nickname }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'productionMangerUser'">
|
||||
<span>{{ record.productionMangerUser ?.nickname }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'documentUser'">
|
||||
<span>{{ record.documentUser ?.nickname }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'classManagerUser'">
|
||||
<span>{{ record.classManagerUser?.nickname }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
<a-tooltip :title="`${toDateString(record.createTime)}`">
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openInfo(record, 0)">查看安装单派单详情</a>
|
||||
<a @click="openInfo(record, 1)">查看加高单派单详情</a>
|
||||
<a @click="openInfo(record, 2)">查看拆卸单派单详情</a>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
</div>
|
||||
<Info v-model:visible="showInfo" :data="current" :work-type="workType"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, createVNode, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import {
|
||||
ExclamationCircleOutlined,
|
||||
UserOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { toDateString } from "ele-admin-pro";
|
||||
import Info from "./info.vue";
|
||||
import { timeAgo } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import {
|
||||
Worksheet,
|
||||
WORKSHEET_EQUIPMENT_TYPE,
|
||||
WORKSHEET_STATUS_LIST, WORKSHEET_WORK_TYPE,
|
||||
WorksheetParam
|
||||
} from "@/api/tower/worksheet/model";
|
||||
import { pageWorksheet, removeBatchWorksheet, removeWorksheet } from "@/api/tower/worksheet";
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<Worksheet[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<Worksheet | null>(null);
|
||||
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示批量移动弹窗
|
||||
const showMove = ref(false);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
if (filters) {
|
||||
where.status = filters.status;
|
||||
}
|
||||
return pageWorksheet({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: "项目名称",
|
||||
dataIndex: "projectName"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 400,
|
||||
align: "center",
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: WorksheetParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
|
||||
const showSettle = ref<Boolean>(false);
|
||||
const openSettle = (row?: Worksheet) => {
|
||||
current.value = row ?? null;
|
||||
showSettle.value = true;
|
||||
};
|
||||
|
||||
/* 打开批量移动弹窗 */
|
||||
const openMove = () => {
|
||||
showMove.value = true;
|
||||
};
|
||||
|
||||
const workType = ref<number>(0)
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row: Worksheet, workTypeValue: number) => {
|
||||
current.value = row;
|
||||
workType.value = workTypeValue;
|
||||
showInfo.value = true;
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: Worksheet) => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeWorksheet(row.worksheetId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量转移 */
|
||||
const batchMove = (userId) => {
|
||||
console.log(userId, "批量转移0000");
|
||||
console.log(selection.value);
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定要删除选中的记录吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchWorksheet(
|
||||
selection.value.map((d) => {
|
||||
return d.worksheetId;
|
||||
})
|
||||
)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Accessory"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
259
src/views/tower/installNApartManage/worksheet/info.vue
Normal file
259
src/views/tower/installNApartManage/worksheet/info.vue
Normal file
@@ -0,0 +1,259 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="`80%`"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:maxable="maxAble"
|
||||
title="派单详情"
|
||||
:body-style="{ paddingBottom: '8px', background: '#f3f3f3' }"
|
||||
@update:visible="updateVisible"
|
||||
:maskClosable="false"
|
||||
:footer="null"
|
||||
@ok="save"
|
||||
>
|
||||
<a-collapse v-model:activeKey="activeKey" accordion v-if="visible">
|
||||
<a-collapse-panel
|
||||
:header="`标地:${info.address}(审核状态:${WORKSHEET_AUDIT_STATUS_LIST[info.auditStatus]},当前状态:${WORKSHEET_STATUS_LIST[info.status]})`"
|
||||
v-for="(info, index) in list" :key="index.toString()">
|
||||
<a-card>
|
||||
<a-descriptions title="人员信息">
|
||||
<a-descriptions-item :label="`审核人${auditIndex + 1}`" v-for="(audit, auditIndex) in info.auditList"
|
||||
:key="auditIndex">{{ audit.nickname }}({{ audit.auditStatus === 1 ? "审核通过" : (audit.auditStatus === 2 ? "审核不通过" : "未审核")
|
||||
}})
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="资料员">{{ info.documentUser?.nickname }}({{ info.documentDoneTime ? `完成时间:${dayjs(info.documentDoneTime).format("YYYY-MM-DD HH:mm:ss")}` : "待完成"
|
||||
}})
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="资产管理员">{{ info.assetUser?.nickname }}({{ info.assetDoneTime ? `完成时间:${dayjs(info.assetDoneTime).format('YYYY-MM-DD HH:mm:ss')}` : '待完成' }})
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="维保人员">{{ info.fixUser?.nickname }}({{ info.fixDoneTime ? `完成时间:${dayjs(info.fixDoneTime).format('YYYY-MM-DD HH:mm:ss')}` : "待完成"
|
||||
}})
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="生产主管">{{ info.productionMangerUser?.nickname }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="班组组长">{{ info.classManagerUser?.nickname }}({{ info.status >= 4 ? '已到场' : '待完成' }})
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="车辆调度员">{{ info.carDispatchUser?.nickname }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
<a-card>
|
||||
<a-descriptions title="项目信息">
|
||||
<a-descriptions-item label="派单类型">{{ WORKSHEET_WORK_TYPE[info.detail.workType] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="项目名称">{{ info.projectName }}</a-descriptions-item>
|
||||
<!-- <a-descriptions-item label="项目地址">{{ info.projectRegion + info.projectAddress }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<a-descriptions-item label="计划进场时间">{{ info.planInDate }}</a-descriptions-item>
|
||||
<a-descriptions-item label="到货时间">{{ info.receiveDate }}</a-descriptions-item>
|
||||
<a-descriptions-item label="项目联系人电话"> {{ info.contactPhone }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
<a-card>
|
||||
<a-descriptions title="设备信息">
|
||||
<a-descriptions-item label="设备名称">{{ info.detail?.equipmentName }}</a-descriptions-item>
|
||||
<a-descriptions-item label="作业类型">{{ WORKSHEET_TYPE[info.detail?.workType] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="设备型号">{{ info.detail?.model }}</a-descriptions-item>
|
||||
<a-descriptions-item label="出厂编号">{{ info.detail?.factoryNo }}</a-descriptions-item>
|
||||
<a-descriptions-item label="设备厂家">{{ info.detail.equipment.manufactor }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="安装臂长">{{ info.detail?.setupLength }}</a-descriptions-item>
|
||||
<a-descriptions-item label="年份要求"> {{ info.detail?.yearRequest }}</a-descriptions-item>
|
||||
<a-descriptions-item label="初始安装高度">{{ info.detail?.setupHeight }}米</a-descriptions-item>
|
||||
<a-descriptions-item label="最终安装高度">{{ info.detail?.finalSetupHeight }}米
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="是否需要油漆">{{ TRUE_OR_FALSE[info.detail?.needPaint] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="是否确认道路通畅">{{ TRUE_OR_FALSE[info.detail?.confirmRoad] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="是否确认电箱到位">{{ TRUE_OR_FALSE[info.detail?.confirmElectric] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="是否确认基础预埋时间满足">
|
||||
{{ TRUE_OR_FALSE[info.detail?.confirmHasTime] }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="是否确认安装资料完善"> {{ TRUE_OR_FALSE[info.detail?.confirmProfile]
|
||||
}}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
<a-card>
|
||||
<a-descriptions title="派单信息">
|
||||
<a-descriptions-item label="作业人员">{{ info.detail?.sysWorkerList }}</a-descriptions-item>
|
||||
<a-descriptions-item label="外调人员">{{ info.detail?.outComeWorkerList }}</a-descriptions-item>
|
||||
<a-descriptions-item label="人员类型">
|
||||
{{ (info.detail) ? WORKER_TYPE[info.detail?.workerType] : "" }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="班组负责人">{{ info.classManagerUser?.nickname }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="现场负责人">{{ info.detail?.localeManager }}</a-descriptions-item>
|
||||
<!-- <a-descriptions-item label="司机"> {{ info.detail?.driver }}</a-descriptions-item>-->
|
||||
<!-- <a-descriptions-item label="车牌">{{ info.detail?.carPlate }}</a-descriptions-item>-->
|
||||
<a-descriptions-item label="派单说明">{{ info.detail?.intro }}</a-descriptions-item>
|
||||
<a-descriptions-item label="备注信息">{{ info.detail?.remark }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<a-descriptions title="资料图片" v-if="info.detail && info.detail?.photos">
|
||||
<a-descriptions-item>
|
||||
<a-image-preview-group>
|
||||
<a-image style="margin-right: 1rem"
|
||||
:width="45"
|
||||
v-for="(item, index) in info.detail?.photos.split(',')"
|
||||
:key="index"
|
||||
:src="item"
|
||||
/>
|
||||
</a-image-preview-group>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<!-- <a-card title="配件信息">-->
|
||||
<!-- <a-descriptions v-for="(item, index) in parts" :key="index" :title="item.title">-->
|
||||
<!-- <a-descriptions-item v-for="(part, partIndex) in item.children" :key="partIndex"-->
|
||||
<!-- :label="part.partsTitle">-->
|
||||
<!-- x{{ part.num }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
<!-- </a-card>-->
|
||||
</a-card>
|
||||
<a-card>
|
||||
<a-descriptions title="安装信息">
|
||||
<a-descriptions-item label="最高安装高度">{{ info.setUp?.maxSetUpHeight }}米
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="安装高度">{{ info.setUp?.setUpHeight }}米</a-descriptions-item>
|
||||
<a-descriptions-item label="附着高度">{{ info.setUp?.clingHeight }}米</a-descriptions-item>
|
||||
<a-descriptions-item label="大臂长度">{{ info.setUp?.bigArmLength }}米</a-descriptions-item>
|
||||
<a-descriptions-item label="平衡长度">{{ info.setUp?.balanceLength }}米</a-descriptions-item>
|
||||
<a-descriptions-item label="计划安装附墙数"> {{ info.setUp?.planSetUpCling }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
<a-card>
|
||||
<a-descriptions title="车辆信息">
|
||||
<a-descriptions-item :label="item.carPlate" v-for="(item, index) in info.carDispatchList"
|
||||
:key="index">{{ item.name }}({{ item.phone }})
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
<a-card title="到场核验信息">
|
||||
<a-descriptions title="资料图片" v-if="info.check && info.check?.photos">
|
||||
<a-descriptions-item>
|
||||
<a-image-preview-group>
|
||||
<a-image style="margin-right: 1rem"
|
||||
:width="45"
|
||||
v-for="(item, index) in info.check?.photos.split(',')"
|
||||
:key="index"
|
||||
:src="item"
|
||||
/>
|
||||
</a-image-preview-group>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<a-descriptions title="核验信息">
|
||||
<a-descriptions-item label="现场定位">{{ info.check?.address }}</a-descriptions-item>
|
||||
<a-descriptions-item label="实际到场时间">{{ info.check?.checkTime }}</a-descriptions-item>
|
||||
<a-descriptions-item label="核验人">{{ info.check?.nickname }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-card>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { Form } from "ant-design-vue";
|
||||
import { useThemeStore } from "@/store/modules/theme";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { getWorksheet, getWorksheetByWordType } from "@/api/tower/worksheet";
|
||||
import {
|
||||
Worksheet,
|
||||
WORKSHEET_AUDIT_STATUS_LIST,
|
||||
WORKSHEET_STATUS_LIST,
|
||||
WORKSHEET_WORK_TYPE
|
||||
} from "@/api/tower/worksheet/model";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const useForm = Form.useForm;
|
||||
// 是否开启响应式布局
|
||||
const themeStore = useThemeStore();
|
||||
const { styleResponsive } = storeToRefs(themeStore);
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Worksheet | null;
|
||||
workType: number;
|
||||
}>();
|
||||
|
||||
// 是否显示最大化切换按钮
|
||||
const maxAble = ref(true);
|
||||
|
||||
const active = ref(2);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 请求状态
|
||||
const loading = ref(true);
|
||||
|
||||
const activeKey = ref<string[]>();
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
const WORKSHEET_TYPE = ["安装单", "加高单", "拆卸单"];
|
||||
const TRUE_OR_FALSE = ["否", "是"];
|
||||
const WORKER_TYPE = ["自有", "外派"];
|
||||
|
||||
const list = ref<Worksheet[]>([]);
|
||||
|
||||
const parts = ref<any>([]);
|
||||
|
||||
const getDetail = () => {
|
||||
const projectId = props.data?.projectId;
|
||||
list.value = [];
|
||||
getWorksheetByWordType(projectId, props.workType).then((data) => {
|
||||
list.value = data;
|
||||
// for (let key in data) info[key] = data[key];
|
||||
// parts.value = [];
|
||||
// if (info.parts) {
|
||||
// const parentIdIdList = [];
|
||||
// info.parts.forEach((item: any) => {
|
||||
// if (parentIdIdList.indexOf(item.parentId) === -1) {
|
||||
// parentIdIdList.push(item.parentId);
|
||||
// parts.value.push({
|
||||
// title: item.parentPartsTitle,
|
||||
// parentId: item.parentId,
|
||||
// children: []
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// info.parts.forEach(item => {
|
||||
// parts.value.forEach((parent, index) => {
|
||||
// if (item.parentId === parent.parentId) parts.value[index].children.push(item);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
});
|
||||
};
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
getDetail();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
384
src/views/tower/invoicing/components/edit.vue
Normal file
384
src/views/tower/invoicing/components/edit.vue
Normal file
@@ -0,0 +1,384 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="'90%'"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:maskClosable="false"
|
||||
:maxable="maxable"
|
||||
:title="isUpdate ? '编辑开票' : '添加开票'"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
@ok="save"
|
||||
>
|
||||
<a-form
|
||||
:label-col="{ md: { span: 4 }, sm: { span: 4 }, xs: { span: 4 } }"
|
||||
:label-align="'left'"
|
||||
:wrapper-col="{ md: { span: 24 }, sm: { span: 20 }, xs: { span: 24 } }"
|
||||
>
|
||||
<a-card title="填报人信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<a-form-item label="填报人">
|
||||
<a-input disabled v-model:value="loginUser.username" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<a-form-item label="填报时间">
|
||||
<a-input disabled v-model:value="now" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-card title="合同信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="合同编号" v-bind="validateInfos.contractId">
|
||||
<TowerContractSelectModel
|
||||
:placeholder="`请选择合同`"
|
||||
v-model:value="form.contractNumber"
|
||||
@done="chooseContract"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="承租单位">
|
||||
<p style="margin: 0">{{ form.customerName }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="签订日期">
|
||||
<p style="margin: 0">{{ form.signDate }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="租赁单位">
|
||||
<p style="margin: 0">{{ form.companyName }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="项目名称">
|
||||
<p style="margin: 0">{{ form.projectName }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="累计开票金额">
|
||||
<p style="margin: 0">{{ form.totalInvoicingAmount }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-card title="开票信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="开票日期" v-bind="validateInfos.invoicingDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择开票日期"
|
||||
v-model:value="form.invoicingDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="开票金额" v-bind="validateInfos.invoicingAmount">
|
||||
<a-input v-model:value="form.invoicingAmount" placeholder="请输入开票金额" type="number">
|
||||
<template #addonAfter>元</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="开票单位" v-bind="validateInfos.invoicingCompany">
|
||||
<SelectCompany
|
||||
:placeholder="`请选择开票单位`"
|
||||
v-model:value="form.invoicingCompany"
|
||||
@done="chooseCompany"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="发票编号">
|
||||
<a-input v-model:value="form.invoicingNo" placeholder="请输入发票编号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="申请人">
|
||||
<a-input v-model:value="form.requestName" placeholder="请输入申请人" />
|
||||
</a-form-item>
|
||||
<a-form-item label="登记人" v-bind="validateInfos.signName">
|
||||
<UserChoose @select="selectSignName" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item label="备注" :label-col="{ md: { span: 1 }, sm: { span: 1 }, xs: { span: 1 } }">
|
||||
<a-input v-model:value="form.remark" placeholder="请输入备注说明" />
|
||||
</a-form-item>
|
||||
<a-form-item label="附件" name="parentId">
|
||||
<a-upload
|
||||
v-model:file-list="fileList"
|
||||
name="file"
|
||||
action="https://file.wsdns.cn/api/file/image"
|
||||
:headers="{ Authorization: token }"
|
||||
@change="onFile"
|
||||
>
|
||||
<a-button>
|
||||
<upload-outlined />
|
||||
上传
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</a-form-item>
|
||||
</a-card>
|
||||
<a-card title="结算单分摊">
|
||||
<a-button @click.native="showSelectSettle = true" type="primary" :disabled="!form.contractId">新增
|
||||
</a-button>
|
||||
<Table :data-source="settleList" />
|
||||
</a-card>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
<ele-modal
|
||||
:width="'80%'"
|
||||
:visible="showSelectSettle"
|
||||
:maskClosable="false"
|
||||
title="选择结算单"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="showSelectSettle"
|
||||
@cancel="showSelectSettle = false"
|
||||
@ok="showSelectSettle = false"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="6">结算状态</a-col>
|
||||
<a-col :span="6">结算单号</a-col>
|
||||
<a-col :span="6">本期结算金额</a-col>
|
||||
<a-col :span="6">操作</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" class="my-05" v-for="(item, index) in contractSettleList" :key="index">
|
||||
<a-col :span="6">{{ SETTLE_STATUS_LIST[item.status] }}</a-col>
|
||||
<a-col :span="6">{{ item.settleNo }}</a-col>
|
||||
<a-col :span="6">{{ item.totalAmount }}</a-col>
|
||||
<a-col :span="6">
|
||||
<a-button type="link" @click.native="selectSettle(item)">选择</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, computed } from "vue";
|
||||
import { Form, message } from "ant-design-vue";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import dayjs from "dayjs";
|
||||
import { Contract } from "@/api/tower/contract/model";
|
||||
import Table from "./table.vue";
|
||||
import { Invoicing } from "@/api/tower/invoicing/model";
|
||||
import { addInvoicing, updateInvoicing } from "@/api/tower/invoicing";
|
||||
import { Company } from "@/api/system/company/model";
|
||||
import { User } from "@/api/user/model";
|
||||
import { TOKEN_STORE_NAME } from "@/config/setting";
|
||||
import { UploadOutlined } from "@ant-design/icons-vue";
|
||||
import { Settle, SETTLE_STATUS_LIST } from "@/api/tower/settle/model";
|
||||
import { listSettle } from "@/api/tower/settle";
|
||||
import { InvoicingSettle } from "@/api/tower/invoicingSettle/model";
|
||||
import { addBatchInvoicingSettle } from "@/api/tower/invoicingSettle";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const token = localStorage.getItem(TOKEN_STORE_NAME);
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
const useForm = Form.useForm;
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Invoicing | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
// 是否显示最大化切换按钮
|
||||
const maxable = ref(true);
|
||||
const activeKey = ref(0);
|
||||
|
||||
const contractSettleList = ref<Settle[]>([]);
|
||||
const getContractSettleList = async contractId => {
|
||||
contractSettleList.value = await listSettle({ contractId });
|
||||
};
|
||||
|
||||
const showSelectSettle = ref(false);
|
||||
const selectSettle = (item: Settle) => {
|
||||
settleList.value.push({
|
||||
invoicingId: null,
|
||||
settleNumber: item.settleNo,
|
||||
startDate: item.startDate,
|
||||
settleAmount: item.totalAmount
|
||||
});
|
||||
showSelectSettle.value = false;
|
||||
};
|
||||
const settleList = ref<InvoicingSettle[]>([]);
|
||||
|
||||
const chooseContract = (res: Contract) => {
|
||||
form.contractNumber = res.contactNumber;
|
||||
form.contractId = res.contractId;
|
||||
form.companyName = res.companyName;
|
||||
form.customerName = res.customerName;
|
||||
form.signDate = res.signDate;
|
||||
form.projectName = res.projectName;
|
||||
getContractSettleList(res.contractId);
|
||||
};
|
||||
|
||||
const chooseCompany = ({ companyName }: Company) => {
|
||||
form.invoicingCompany = companyName;
|
||||
};
|
||||
|
||||
const selectSignName = ({ nickname }: User) => {
|
||||
form.signName = nickname;
|
||||
};
|
||||
|
||||
const fileList = ref<FileItem[]>([]);
|
||||
|
||||
interface FileItem {
|
||||
uid: string;
|
||||
name?: string;
|
||||
status?: string;
|
||||
response?: Response;
|
||||
thumbUrl?: string;
|
||||
downloadUrl?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface FileInfo {
|
||||
file: FileItem;
|
||||
fileList: FileItem[];
|
||||
}
|
||||
|
||||
const onFile = (info: FileInfo) => {
|
||||
let resFileList = [...info.fileList];
|
||||
fileList.value = resFileList.map((file) => {
|
||||
if (file.response) {
|
||||
file.url = file.response.url;
|
||||
}
|
||||
return file;
|
||||
});
|
||||
form.fileList = JSON.stringify(fileList.value);
|
||||
};
|
||||
|
||||
const form = reactive<Invoicing>({
|
||||
invoicingId: "",
|
||||
contractId: "",
|
||||
contractNumber: "",
|
||||
signDate: "",
|
||||
projectName: "",
|
||||
customerName: "",
|
||||
companyName: "",
|
||||
invoicingDate: "",
|
||||
invoicingCompany: "",
|
||||
invoicingAmount: "",
|
||||
fileList: "[]",
|
||||
remark: "",
|
||||
userId: loginUser.value.userId,
|
||||
totalInvoicingAmount: "",
|
||||
signName: loginUser.value.username,
|
||||
requestName: ""
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
contractId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择合同",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
invoicingAmount: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入开票金额",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
invoicingCompany: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择开票单位",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
invoicingDate: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择开票日期",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
signName: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择登记人员",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
|
||||
});
|
||||
const { resetFields, validate, validateInfos } = useForm(form, rules);
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
validate()
|
||||
.then(async () => {
|
||||
loading.value = true;
|
||||
const data = {
|
||||
...form
|
||||
};
|
||||
const saveOrUpdate = isUpdate.value ? updateInvoicing : addInvoicing;
|
||||
const res = await saveOrUpdate(data).catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
if (settleList.value.length > 0) {
|
||||
const invoicingId = res?.data;
|
||||
settleList.value.forEach((item, index) => {
|
||||
settleList.value[index].invoicingId = invoicingId;
|
||||
});
|
||||
await addBatchInvoicingSettle(settleList.value);
|
||||
}
|
||||
message.success(res?.message);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(form, props.data);
|
||||
isUpdate.value = true;
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
148
src/views/tower/invoicing/components/info.vue
Normal file
148
src/views/tower/invoicing/components/info.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="75%"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:title="'合同详情'"
|
||||
:maxable="true"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
:footer="null"
|
||||
>
|
||||
<a-form
|
||||
:label-col="{ md: { span: 4 }, sm: { span: 24 } }"
|
||||
:wrapper-col="{ md: { span: 19 }, sm: { span: 24 } }"
|
||||
>
|
||||
<div class="base-form" style="margin-bottom: 20px">
|
||||
<a-descriptions bordered>
|
||||
<a-descriptions-item label="合同名称">
|
||||
{{ customer.customerName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="社会统一信用代码">
|
||||
{{ customer.customerCode }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="跟进状态">
|
||||
<div color="blue" v-for="(d, index) in progress" :key="index">
|
||||
<span v-if="d.value == customer.progress">{{ d.label }}</span>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系人">
|
||||
{{ customer.customerContacts }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系电话">
|
||||
{{ customer.customerMobile }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="座机电话">
|
||||
{{ customer.customerPhone }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="合同类型">
|
||||
<div color="blue" v-for="(d, index) in customerType" :key="index">
|
||||
<span v-if="d.value == customer.customerType">{{ d.value }}</span>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系地址">
|
||||
{{ customer.customerAddress }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="备注">
|
||||
{{ customer.comments }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<!-- <a-descriptions-->
|
||||
<!-- title="其他信息"-->
|
||||
<!-- :column="1"-->
|
||||
<!-- bordered-->
|
||||
<!-- style="margin-top: 30px"-->
|
||||
<!-- >-->
|
||||
<!-- <a-descriptions-item label="相关项目">-->
|
||||
<!-- {{ customer.comments }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import { assignObject } from 'ele-admin-pro';
|
||||
import type { Customer } from '@/api/oa/customer/model';
|
||||
import { FILE_SERVER } from '@/config/setting';
|
||||
import { getDictionaryOptions } from '@/utils/common';
|
||||
|
||||
const useForm = Form.useForm;
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Customer | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done'): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 用户信息
|
||||
const customer = reactive<Customer>({
|
||||
customerCode: '',
|
||||
customerName: '',
|
||||
customerType: undefined,
|
||||
customerMobile: '',
|
||||
customerAvatar: '',
|
||||
customerPhone: '',
|
||||
customerContacts: '',
|
||||
customerAddress: '',
|
||||
comments: '',
|
||||
progress: '',
|
||||
status: '0',
|
||||
sortNumber: 100,
|
||||
customerId: 0
|
||||
});
|
||||
|
||||
// 请求状态
|
||||
const loading = ref(true);
|
||||
|
||||
const { resetFields } = useForm(customer);
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
|
||||
/* 打开外部链接 */
|
||||
// const openUrl = (record) => {
|
||||
// window.open(record.panel);
|
||||
// };
|
||||
|
||||
/* 获取字典数据 */
|
||||
const customerType = getDictionaryOptions('customerType');
|
||||
const progress = getDictionaryOptions('customerFollowStatus');
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(customer, props.data);
|
||||
}
|
||||
} else {
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style lang="less">
|
||||
.tab-pane {
|
||||
min-height: 100px;
|
||||
}
|
||||
.card-head {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
205
src/views/tower/invoicing/components/search.vue
Normal file
205
src/views/tower/invoicing/components/search.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<a-space :size="10" style="flex-wrap: wrap">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
<span>新增</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
v-if="selection.length > 0"
|
||||
@click="removeBatch"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
<span>批量删除</span>
|
||||
</a-button>
|
||||
<!-- <a-button @click="batchMove" v-if="selection.length > 0">-->
|
||||
<!-- <template #icon>-->
|
||||
<!-- <UserSwitchOutlined />-->
|
||||
<!-- </template>-->
|
||||
<!-- 批量转移-->
|
||||
<!-- </a-button>-->
|
||||
<a-input-search
|
||||
allow-clear
|
||||
placeholder="请输入关键词"
|
||||
v-model:value="searchText"
|
||||
@pressEnter="search"
|
||||
@search="search"
|
||||
/>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
PlusOutlined,
|
||||
DeleteOutlined,
|
||||
UploadOutlined,
|
||||
DownloadOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import useSearch from '@/utils/use-search';
|
||||
import type { CustomerParam } from '@/api/oa/customer/model';
|
||||
import { ref, watch } from 'vue';
|
||||
import { utils, read } from 'xlsx';
|
||||
// import { assignObject } from 'ele-admin-pro';
|
||||
import { message } from 'ant-design-vue/es';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
// 选中的角色
|
||||
selection?: [];
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search', where?: CustomerParam): void;
|
||||
(e: 'add'): void;
|
||||
(e: 'remove'): void;
|
||||
(e: 'batchMove'): void;
|
||||
}>();
|
||||
|
||||
// 表单数据
|
||||
const { where } = useSearch<CustomerParam>({
|
||||
name: '',
|
||||
creditCode: '',
|
||||
keywords: '',
|
||||
userId: undefined
|
||||
});
|
||||
// 下来选项
|
||||
// 搜索内容
|
||||
const searchText = ref('');
|
||||
|
||||
/* 搜索 */
|
||||
const search = () => {
|
||||
where.keywords = searchText.value;
|
||||
emit('search', where);
|
||||
};
|
||||
|
||||
// 新增
|
||||
const add = () => {
|
||||
emit('add');
|
||||
};
|
||||
|
||||
// 导入数据的列
|
||||
const importTitle = ref<string[]>(['A', 'B', 'C', 'D', 'E', 'F', 'G']);
|
||||
// 导入的数据
|
||||
const importData = ref<Record<string, any>[]>([]);
|
||||
// 导入数据二维数组形式
|
||||
const importDataAoa = ref<(string | number)[][]>([]);
|
||||
|
||||
/* 导入本地 excel 文件 */
|
||||
const importBatch = (file: File) => {
|
||||
if (
|
||||
![
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
].includes(file.type)
|
||||
) {
|
||||
message.error('只能选择 excel 文件');
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
message.error('大小不能超过 20MB');
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target?.result as any);
|
||||
const workbook = read(data, { type: 'array' });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
// 生成表格需要的数据
|
||||
let list: Record<string, any>[] = [];
|
||||
let maxCols = 0;
|
||||
let title: string[] = [];
|
||||
aoa.forEach((d) => {
|
||||
if (d.length > maxCols) {
|
||||
maxCols = d.length;
|
||||
}
|
||||
const row = {};
|
||||
for (let i = 0; i < d.length; i++) {
|
||||
const key = getCharByIndex(i);
|
||||
row[key] = d[i];
|
||||
row['__colspan__' + key] = 1;
|
||||
row['__rowspan__' + key] = 1;
|
||||
}
|
||||
list.push(row);
|
||||
});
|
||||
for (let i = 0; i < maxCols; i++) {
|
||||
title.push(getCharByIndex(i));
|
||||
}
|
||||
importTitle.value = title;
|
||||
importData.value = list;
|
||||
importDataAoa.value = aoa;
|
||||
};
|
||||
console.log(importData.value);
|
||||
console.log(importDataAoa.value);
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
};
|
||||
/* 生成Excel列字母序号 */
|
||||
const getCharByIndex = (index: number) => {
|
||||
const chars = [
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z'
|
||||
];
|
||||
if (index < chars.length) {
|
||||
return chars[index];
|
||||
}
|
||||
const n = parseInt(String(index / chars.length));
|
||||
const m = index % chars.length;
|
||||
return chars[n] + chars[m];
|
||||
};
|
||||
|
||||
// 转移
|
||||
// const batchMove = () => {
|
||||
// emit('batchMove');
|
||||
// };
|
||||
|
||||
// 批量删除
|
||||
const removeBatch = () => {
|
||||
emit('remove');
|
||||
};
|
||||
|
||||
const onClear = () => {
|
||||
where.userId = undefined;
|
||||
search();
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.selection,
|
||||
() => {}
|
||||
);
|
||||
</script>
|
||||
85
src/views/tower/invoicing/components/table.vue
Normal file
85
src/views/tower/invoicing/components/table.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<a-table ref="tableRef"
|
||||
row-key="contractSettleId" :dataSource="dataList" :columns="columns">
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'shareAmount'">
|
||||
<a-input v-model:value="record.shareAmount" type="number">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<div class="flex justify-center items-center">
|
||||
<close-circle-outlined style="font-size: 1.5rem; color: pink;cursor: pointer"
|
||||
@click.native="del(index)" />
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { ColumnItem } from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import {
|
||||
CloseCircleOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import { InvoicingSettle } from "@/api/tower/invoicingSettle/model";
|
||||
|
||||
const props = defineProps<{
|
||||
dataSource: InvoicingSettle[]
|
||||
}>();
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
const emits = defineEmits(["total"]);
|
||||
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: "序号",
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 1)
|
||||
},
|
||||
{
|
||||
title: "结算编号",
|
||||
dataIndex: "settleNumber"
|
||||
},
|
||||
{
|
||||
title: "结算所属年月",
|
||||
dataIndex: "startDate"
|
||||
},
|
||||
{
|
||||
title: "结算金额",
|
||||
dataIndex: "settleAmount"
|
||||
},
|
||||
{
|
||||
title: "分摊开票金额",
|
||||
dataIndex: "shareAmount",
|
||||
key: "shareAmount"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "action",
|
||||
key: "action"
|
||||
}
|
||||
]);
|
||||
|
||||
const dataList = ref<InvoicingSettle[]>([]);
|
||||
|
||||
const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
defineExpose({ dataList });
|
||||
</script>
|
||||
282
src/views/tower/invoicing/index.vue
Normal file
282
src/views/tower/invoicing/index.vue
Normal file
@@ -0,0 +1,282 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="invoicingId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 800 }"
|
||||
class="sys-org-table"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@batchMove="openMove"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<span>{{ INVOICING_STATUS_LIST[record.status] }}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
<a-tooltip :title="`${toDateString(record.createTime)}`">
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="确定要删除此记录吗?"
|
||||
@confirm="remove(record)"
|
||||
>
|
||||
<a class="ele-text-danger">删除</a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<Edit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
<!-- 合同详情弹窗 -->
|
||||
<Info v-model:visible="showInfo" :data="current" @done="reload" />
|
||||
<!-- 批量转移弹窗 -->
|
||||
<!-- <CustomerMove v-model:visible="showMove" :data="selection" @done="batchMove" />-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, createVNode, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import {
|
||||
ExclamationCircleOutlined,
|
||||
UserOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { toDateString } from "ele-admin-pro";
|
||||
import Search from "./components/search.vue";
|
||||
import Edit from "./components/edit.vue";
|
||||
import Info from "./components/info.vue";
|
||||
import { timeAgo } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { Invoicing, INVOICING_STATUS_LIST, InvoicingParam } from "@/api/tower/invoicing/model";
|
||||
import { pageInvoicing, removeBatchInvoicing, removeInvoicing } from "@/api/tower/invoicing";
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<Invoicing[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<Invoicing | null>(null);
|
||||
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 是否显示批量移动弹窗
|
||||
const showMove = ref(false);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
if (filters) {
|
||||
where.status = filters.status;
|
||||
}
|
||||
return pageInvoicing({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: "开票状态",
|
||||
dataIndex: "status",
|
||||
key: "status",
|
||||
},
|
||||
{
|
||||
title: "开票日期",
|
||||
dataIndex: "invoicingDate"
|
||||
},
|
||||
{
|
||||
title: "合同编号",
|
||||
dataIndex: "contactNumber"
|
||||
},
|
||||
{
|
||||
title: "项目名称",
|
||||
dataIndex: "projectName"
|
||||
},
|
||||
{
|
||||
title: "承租单位",
|
||||
dataIndex: "customerName"
|
||||
},
|
||||
{
|
||||
title: "申请人",
|
||||
dataIndex: "requestName"
|
||||
},
|
||||
{
|
||||
title: "开票单位",
|
||||
dataIndex: "invoicingCompany"
|
||||
},
|
||||
{
|
||||
title: "开票金额",
|
||||
dataIndex: "invoicingAmount"
|
||||
},
|
||||
{
|
||||
title: "发票号",
|
||||
dataIndex: "invoicingNo"
|
||||
},
|
||||
{
|
||||
title: "申请人",
|
||||
dataIndex: "requestName"
|
||||
},
|
||||
{
|
||||
title: "备注",
|
||||
dataIndex: "remark"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 200,
|
||||
align: "center",
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: InvoicingParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Invoicing) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
|
||||
const showSettle = ref<Boolean>(false);
|
||||
const openSettle = (row?: Invoicing) => {
|
||||
current.value = row ?? null;
|
||||
showSettle.value = true;
|
||||
};
|
||||
|
||||
/* 打开批量移动弹窗 */
|
||||
const openMove = () => {
|
||||
showMove.value = true;
|
||||
};
|
||||
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row?: Invoicing) => {
|
||||
current.value = row ?? null;
|
||||
showInfo.value = true;
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: Invoicing) => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeInvoicing(row.invoicingId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量转移 */
|
||||
const batchMove = (userId) => {
|
||||
console.log(userId, "批量转移0000");
|
||||
console.log(selection.value);
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定要删除选中的记录吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchInvoicing(
|
||||
selection.value.map((d) => {
|
||||
if (loginUser.value.userId === d.userId) {
|
||||
return d.invoicingId;
|
||||
}
|
||||
})
|
||||
)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Accessory"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
337
src/views/tower/lending/components/edit.vue
Normal file
337
src/views/tower/lending/components/edit.vue
Normal file
@@ -0,0 +1,337 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="'90%'"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:maskClosable="false"
|
||||
:maxable="maxable"
|
||||
:title="isUpdate ? '编辑转租结算' : '添加转租结算'"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
@ok="save"
|
||||
>
|
||||
<a-form
|
||||
:label-col="{ md: { span: 6 }, sm: { span: 20 }, xs: { span: 24 } }"
|
||||
:wrapper-col="{ md: { span: 24 }, sm: { span: 20 }, xs: { span: 24 } }"
|
||||
>
|
||||
<a-card title="填报人信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<a-form-item label="填报人">
|
||||
<a-input disabled v-model:value="loginUser.username" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="12" :sm="24" :xs="24">
|
||||
<a-form-item label="填报时间">
|
||||
<a-input disabled v-model:value="now" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-card title="合同信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="合同编号" v-bind="validateInfos.contractId">
|
||||
<TowerContractSelectModel
|
||||
:placeholder="`请选择合同`"
|
||||
v-model:value="form.contactNumber"
|
||||
@done="chooseContract"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="承租单位">
|
||||
<p style="margin: 0">{{ form.customerName }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="签订日期">
|
||||
<p style="margin: 0">{{ form.signDate }}</p>
|
||||
</a-form-item>
|
||||
<a-form-item label="租赁单位">
|
||||
<p style="margin: 0">{{ form.companyName }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="项目名称">
|
||||
<p style="margin: 0">{{ form.projectName }}</p>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<a-card title="结算信息" :bordered="false">
|
||||
<a-row :gutter="16">
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="产权单位" v-bind="validateInfos.amountWithTax">
|
||||
<DictSelect
|
||||
dict-code="PropertyCompany"
|
||||
placeholder="请选择产权单位"
|
||||
v-model:value="form.propertyCompany"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="结算日期">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择结束日期"
|
||||
v-model:value="form.settleDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="本期结算金额">
|
||||
<a-input v-model:value="form.settleAmount" disabled placeholder="自动计算">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item label="备注">
|
||||
<a-input v-model:value="form.remark" placeholder="请输入备注说明" />
|
||||
</a-form-item>
|
||||
</a-card>
|
||||
<a-card title="结算清单">
|
||||
<a-button @click.native="showSelectEquipment = true" type="primary"
|
||||
:disabled="!form.contractId || settleList.length === contractEquipmentList.length">新增
|
||||
</a-button>
|
||||
<Table :data-source="settleList" @total="setTotal" />
|
||||
</a-card>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
<ele-modal
|
||||
:width="'80%'"
|
||||
:visible="showSelectEquipment"
|
||||
:maskClosable="false"
|
||||
title="选择设备"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="showSelectEquipment"
|
||||
@cancel="showSelectEquipment = false"
|
||||
@ok="showSelectEquipment = false"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="8">设备名称</a-col>
|
||||
<a-col :span="8">设备型号</a-col>
|
||||
<a-col :span="8">操作</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" class="my-05" v-for="(item, index) in contractEquipmentList" :key="index">
|
||||
<a-col :span="8">{{ item.equipmentName }}</a-col>
|
||||
<a-col :span="8">{{ item.equipmentModel }}</a-col>
|
||||
<a-col :span="8">
|
||||
<a-button type="link" @click.native="selectEquipment(item)">选择</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, computed } from "vue";
|
||||
import { Form, message } from "ant-design-vue";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import dayjs from "dayjs";
|
||||
import { addLending, updateLending } from "@/api/tower/lending";
|
||||
import { Lending } from "@/api/tower/lending/model";
|
||||
import { Contract } from "@/api/tower/contract/model";
|
||||
import { ContractSettleEquipment } from "@/api/tower/contractSettle/equipment/model";
|
||||
import { listContractSettleEquipment } from "@/api/tower/contractSettle/equipment";
|
||||
import Table from "@/views/tower/lending/components/table.vue";
|
||||
import { LendingSettle } from "@/api/tower/lendingSettle/model";
|
||||
import { addBatchLendingSettle, listLendingSettle } from "@/api/tower/lendingSettle";
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||
|
||||
const showSelectEquipment = ref(false);
|
||||
const contractEquipmentList = ref<ContractSettleEquipment[]>([]);
|
||||
const settleList = ref<LendingSettle[]>([]);
|
||||
|
||||
const getSettleList = async () => {
|
||||
settleList.value = await listLendingSettle({lendingId: form.lendingId})
|
||||
}
|
||||
|
||||
const getContractEquipmentList = async () => {
|
||||
const contractEquipmentParam = <ContractSettleEquipment>{
|
||||
contractId: form.contractId
|
||||
};
|
||||
contractEquipmentList.value = await listContractSettleEquipment(contractEquipmentParam);
|
||||
settleList.value = [];
|
||||
contractEquipmentList.value.forEach(item => {
|
||||
addSettleList(item);
|
||||
});
|
||||
};
|
||||
|
||||
const selectEquipment = item => {
|
||||
addSettleList(item);
|
||||
showSelectEquipment.value = false;
|
||||
};
|
||||
|
||||
const addSettleList = item => {
|
||||
settleList.value.push({
|
||||
equipmentId: item.equipmentId,
|
||||
lendingId: form.lendingId,
|
||||
equipmentName: item.equipmentName,
|
||||
equipmentModel: item.equipmentModel,
|
||||
equipmentNo: item.equipmentNo,
|
||||
lendingPath: null,
|
||||
coopWay: null,
|
||||
startDate: null,
|
||||
stopDate: null,
|
||||
calDay: null,
|
||||
daysInMonth: null,
|
||||
monthRentAmount: null,
|
||||
shouldPayRentAmount: null,
|
||||
dailyRentAmount: null,
|
||||
shouldSupplementAmount: null,
|
||||
shouldDeductionAmount: null,
|
||||
paidAmount: null,
|
||||
taxRate: null,
|
||||
taxAmount: null,
|
||||
totalAmountWithTax: null,
|
||||
remark: "",
|
||||
userId: loginUser.value.userId
|
||||
});
|
||||
};
|
||||
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
const useForm = Form.useForm;
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Lending | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
// 是否显示最大化切换按钮
|
||||
const maxable = ref(true);
|
||||
const activeKey = ref(0);
|
||||
|
||||
const chooseContract = (res: Contract) => {
|
||||
form.contactNumber = res.contactNumber;
|
||||
form.contractId = res.contractId;
|
||||
form.companyName = res.companyName;
|
||||
form.customerName = res.customerName;
|
||||
form.signDate = res.signDate;
|
||||
form.projectName = res.projectName;
|
||||
getContractEquipmentList();
|
||||
};
|
||||
|
||||
const form = reactive<Lending>({
|
||||
lendingId: "",
|
||||
contractId: "",
|
||||
contactNumber: "",
|
||||
signDate: "",
|
||||
projectName: "",
|
||||
customerName: "",
|
||||
companyName: "",
|
||||
propertyCompany: "",
|
||||
settleDate: "",
|
||||
settleAmount: "",
|
||||
fileList: "",
|
||||
remark: "",
|
||||
userId: loginUser.value.userId
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
contractId: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择合同",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
propertyCompany: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择产权单位",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
settleDate: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择结算日期",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
});
|
||||
const { resetFields, validate, validateInfos } = useForm(form, rules);
|
||||
|
||||
const setTotal = total => {
|
||||
form.settleAmount = total;
|
||||
};
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
validate()
|
||||
.then(async () => {
|
||||
loading.value = true;
|
||||
const data = {
|
||||
...form
|
||||
};
|
||||
if (settleList.value.length === 0) {
|
||||
message.error("请选择结算设备");
|
||||
return;
|
||||
}
|
||||
const saveOrUpdate = isUpdate.value ? updateLending : addLending;
|
||||
const res = await saveOrUpdate(data).catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
const lendingId = res?.data;
|
||||
settleList.value.forEach((item, index) => {
|
||||
settleList.value[index].lendingId = lendingId;
|
||||
});
|
||||
await addBatchLendingSettle(settleList.value);
|
||||
message.success(res?.message);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(form, props.data);
|
||||
isUpdate.value = true;
|
||||
getSettleList()
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
148
src/views/tower/lending/components/info.vue
Normal file
148
src/views/tower/lending/components/info.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="75%"
|
||||
:visible="visible"
|
||||
:confirm-loading="loading"
|
||||
:title="'合同详情'"
|
||||
:maxable="true"
|
||||
:body-style="{ paddingBottom: '8px' }"
|
||||
@update:visible="updateVisible"
|
||||
:footer="null"
|
||||
>
|
||||
<a-form
|
||||
:label-col="{ md: { span: 4 }, sm: { span: 24 } }"
|
||||
:wrapper-col="{ md: { span: 19 }, sm: { span: 24 } }"
|
||||
>
|
||||
<div class="base-form" style="margin-bottom: 20px">
|
||||
<a-descriptions bordered>
|
||||
<a-descriptions-item label="合同名称">
|
||||
{{ customer.customerName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="社会统一信用代码">
|
||||
{{ customer.customerCode }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="跟进状态">
|
||||
<div color="blue" v-for="(d, index) in progress" :key="index">
|
||||
<span v-if="d.value == customer.progress">{{ d.label }}</span>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系人">
|
||||
{{ customer.customerContacts }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系电话">
|
||||
{{ customer.customerMobile }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="座机电话">
|
||||
{{ customer.customerPhone }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="合同类型">
|
||||
<div color="blue" v-for="(d, index) in customerType" :key="index">
|
||||
<span v-if="d.value == customer.customerType">{{ d.value }}</span>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系地址">
|
||||
{{ customer.customerAddress }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="备注">
|
||||
{{ customer.comments }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<!-- <a-descriptions-->
|
||||
<!-- title="其他信息"-->
|
||||
<!-- :column="1"-->
|
||||
<!-- bordered-->
|
||||
<!-- style="margin-top: 30px"-->
|
||||
<!-- >-->
|
||||
<!-- <a-descriptions-item label="相关项目">-->
|
||||
<!-- {{ customer.comments }}-->
|
||||
<!-- </a-descriptions-item>-->
|
||||
<!-- </a-descriptions>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Form } from 'ant-design-vue';
|
||||
import { assignObject } from 'ele-admin-pro';
|
||||
import type { Customer } from '@/api/oa/customer/model';
|
||||
import { FILE_SERVER } from '@/config/setting';
|
||||
import { getDictionaryOptions } from '@/utils/common';
|
||||
|
||||
const useForm = Form.useForm;
|
||||
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Customer | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done'): void;
|
||||
(e: 'update:visible', visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 用户信息
|
||||
const customer = reactive<Customer>({
|
||||
customerCode: '',
|
||||
customerName: '',
|
||||
customerType: undefined,
|
||||
customerMobile: '',
|
||||
customerAvatar: '',
|
||||
customerPhone: '',
|
||||
customerContacts: '',
|
||||
customerAddress: '',
|
||||
comments: '',
|
||||
progress: '',
|
||||
status: '0',
|
||||
sortNumber: 100,
|
||||
customerId: 0
|
||||
});
|
||||
|
||||
// 请求状态
|
||||
const loading = ref(true);
|
||||
|
||||
const { resetFields } = useForm(customer);
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit('update:visible', value);
|
||||
};
|
||||
|
||||
/* 打开外部链接 */
|
||||
// const openUrl = (record) => {
|
||||
// window.open(record.panel);
|
||||
// };
|
||||
|
||||
/* 获取字典数据 */
|
||||
const customerType = getDictionaryOptions('customerType');
|
||||
const progress = getDictionaryOptions('customerFollowStatus');
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
if (props.data) {
|
||||
loading.value = false;
|
||||
assignObject(customer, props.data);
|
||||
}
|
||||
} else {
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style lang="less">
|
||||
.tab-pane {
|
||||
min-height: 100px;
|
||||
}
|
||||
.card-head {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
205
src/views/tower/lending/components/search.vue
Normal file
205
src/views/tower/lending/components/search.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<a-space :size="10" style="flex-wrap: wrap">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
<span>新增</span>
|
||||
</a-button>
|
||||
<a-button
|
||||
danger
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
v-if="selection.length > 0"
|
||||
@click="removeBatch"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
<span>批量删除</span>
|
||||
</a-button>
|
||||
<!-- <a-button @click="batchMove" v-if="selection.length > 0">-->
|
||||
<!-- <template #icon>-->
|
||||
<!-- <UserSwitchOutlined />-->
|
||||
<!-- </template>-->
|
||||
<!-- 批量转移-->
|
||||
<!-- </a-button>-->
|
||||
<a-input-search
|
||||
allow-clear
|
||||
placeholder="请输入关键词"
|
||||
v-model:value="searchText"
|
||||
@pressEnter="search"
|
||||
@search="search"
|
||||
/>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
PlusOutlined,
|
||||
DeleteOutlined,
|
||||
UploadOutlined,
|
||||
DownloadOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import useSearch from '@/utils/use-search';
|
||||
import type { CustomerParam } from '@/api/oa/customer/model';
|
||||
import { ref, watch } from 'vue';
|
||||
import { utils, read } from 'xlsx';
|
||||
// import { assignObject } from 'ele-admin-pro';
|
||||
import { message } from 'ant-design-vue/es';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
// 选中的角色
|
||||
selection?: [];
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search', where?: CustomerParam): void;
|
||||
(e: 'add'): void;
|
||||
(e: 'remove'): void;
|
||||
(e: 'batchMove'): void;
|
||||
}>();
|
||||
|
||||
// 表单数据
|
||||
const { where } = useSearch<CustomerParam>({
|
||||
name: '',
|
||||
creditCode: '',
|
||||
keywords: '',
|
||||
userId: undefined
|
||||
});
|
||||
// 下来选项
|
||||
// 搜索内容
|
||||
const searchText = ref('');
|
||||
|
||||
/* 搜索 */
|
||||
const search = () => {
|
||||
where.keywords = searchText.value;
|
||||
emit('search', where);
|
||||
};
|
||||
|
||||
// 新增
|
||||
const add = () => {
|
||||
emit('add');
|
||||
};
|
||||
|
||||
// 导入数据的列
|
||||
const importTitle = ref<string[]>(['A', 'B', 'C', 'D', 'E', 'F', 'G']);
|
||||
// 导入的数据
|
||||
const importData = ref<Record<string, any>[]>([]);
|
||||
// 导入数据二维数组形式
|
||||
const importDataAoa = ref<(string | number)[][]>([]);
|
||||
|
||||
/* 导入本地 excel 文件 */
|
||||
const importBatch = (file: File) => {
|
||||
if (
|
||||
![
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
].includes(file.type)
|
||||
) {
|
||||
message.error('只能选择 excel 文件');
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
message.error('大小不能超过 20MB');
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target?.result as any);
|
||||
const workbook = read(data, { type: 'array' });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
// 生成表格需要的数据
|
||||
let list: Record<string, any>[] = [];
|
||||
let maxCols = 0;
|
||||
let title: string[] = [];
|
||||
aoa.forEach((d) => {
|
||||
if (d.length > maxCols) {
|
||||
maxCols = d.length;
|
||||
}
|
||||
const row = {};
|
||||
for (let i = 0; i < d.length; i++) {
|
||||
const key = getCharByIndex(i);
|
||||
row[key] = d[i];
|
||||
row['__colspan__' + key] = 1;
|
||||
row['__rowspan__' + key] = 1;
|
||||
}
|
||||
list.push(row);
|
||||
});
|
||||
for (let i = 0; i < maxCols; i++) {
|
||||
title.push(getCharByIndex(i));
|
||||
}
|
||||
importTitle.value = title;
|
||||
importData.value = list;
|
||||
importDataAoa.value = aoa;
|
||||
};
|
||||
console.log(importData.value);
|
||||
console.log(importDataAoa.value);
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
};
|
||||
/* 生成Excel列字母序号 */
|
||||
const getCharByIndex = (index: number) => {
|
||||
const chars = [
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z'
|
||||
];
|
||||
if (index < chars.length) {
|
||||
return chars[index];
|
||||
}
|
||||
const n = parseInt(String(index / chars.length));
|
||||
const m = index % chars.length;
|
||||
return chars[n] + chars[m];
|
||||
};
|
||||
|
||||
// 转移
|
||||
// const batchMove = () => {
|
||||
// emit('batchMove');
|
||||
// };
|
||||
|
||||
// 批量删除
|
||||
const removeBatch = () => {
|
||||
emit('remove');
|
||||
};
|
||||
|
||||
const onClear = () => {
|
||||
where.userId = undefined;
|
||||
search();
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.selection,
|
||||
() => {}
|
||||
);
|
||||
</script>
|
||||
258
src/views/tower/lending/components/table.vue
Normal file
258
src/views/tower/lending/components/table.vue
Normal file
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<a-table ref="tableRef"
|
||||
row-key="contractSettleId" :dataSource="dataList" :columns="columns" :scroll="{ x: 4000, y: 300 }">
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'startDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择开始日期"
|
||||
v-model:value="record.startDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
@change="changeDate($event, index)"
|
||||
@ok="changeDate($event, index)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'endDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择结束日期"
|
||||
v-model:value="record.stopDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
@change="changeDate($event, index)"
|
||||
@ok="changeDate($event, index)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'daysInMonth'">
|
||||
<a-input v-model:value="record.daysInMonth" type="number" @change="changeDate($event, index)">
|
||||
<template #suffix>天</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'monthRentAmount'">
|
||||
<a-input v-model:value="record.monthRentAmount" type="number" @change="changeDate($event, index)">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'dailyRentAmount'">
|
||||
<a-input v-model:value="record.dailyRentAmount" type="number" @change="changeDate($event, index)">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'shouldPayRentAmount'">
|
||||
<a-input v-model:value="record.shouldPayRentAmount" type="number">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'shouldSupplementAmount'">
|
||||
<a-input v-model:value="record.shouldSupplementAmount" type="number">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'shouldDeductionAmount'">
|
||||
<a-input v-model:value="record.shouldDeductionAmount" type="number">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'paidAmount'">
|
||||
<a-input v-model:value="record.paidAmount" type="number">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'taxRate'">
|
||||
<a-input v-model:value="record.taxRate" type="number">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'taxAmount'">
|
||||
<a-input v-model:value="record.taxAmount" type="number">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'totalAmountWithTax'">
|
||||
<a-input v-model:value="record.totalAmountWithTax" type="number" @change="changeTotalAmount">
|
||||
<template #suffix>元</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'remark'">
|
||||
<a-input v-model:value="record.remark" />
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<div class="flex justify-center items-center">
|
||||
<close-circle-outlined style="font-size: 1.5rem; color: pink;cursor: pointer"
|
||||
@click.native="del(index)" />
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { ColumnItem } from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import {
|
||||
CloseCircleOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import dayjs from "dayjs";
|
||||
import { LendingSettle } from "@/api/tower/lendingSettle/model";
|
||||
|
||||
const props = defineProps<{
|
||||
dataSource: LendingSettle[]
|
||||
}>();
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
const emits = defineEmits(["total"]);
|
||||
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: "序号",
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 1)
|
||||
},
|
||||
{
|
||||
title: "设备名",
|
||||
dataIndex: "equipmentName",
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: "出厂编号",
|
||||
dataIndex: "factoryNo",
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: "备案编号",
|
||||
dataIndex: "filingNo",
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: "设备自编号",
|
||||
dataIndex: "equipmentNo",
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: "结算开始日期",
|
||||
dataIndex: "startDate",
|
||||
key: "startDate",
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: "结算结束日期",
|
||||
dataIndex: "endDate",
|
||||
key: "endDate",
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: "计费天数",
|
||||
dataIndex: "calDay",
|
||||
key: "calDay",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "月计费天数",
|
||||
dataIndex: "daysInMonth",
|
||||
key: "daysInMonth",
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: "月租金(元)",
|
||||
dataIndex: "monthRentAmount",
|
||||
key: "monthRentAmount",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "日租金(元)",
|
||||
dataIndex: "dailyRentAmount",
|
||||
key: "dailyRentAmount",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "应付租金(元)",
|
||||
dataIndex: "shouldPayRentAmount",
|
||||
key: "shouldPayRentAmount",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "应补租金(元)",
|
||||
dataIndex: "shouldSupplementAmount",
|
||||
key: "shouldSupplementAmount",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "应扣租金(元)",
|
||||
dataIndex: "shouldDeductionAmount",
|
||||
key: "shouldDeductionAmount",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "实付租金(元)",
|
||||
dataIndex: "paidAmount",
|
||||
key: "paidAmount",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "税率(%)",
|
||||
dataIndex: "taxRate",
|
||||
key: "taxRate",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "税金(元)",
|
||||
dataIndex: "taxAmount",
|
||||
key: "taxAmount",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "税价合计(元)",
|
||||
dataIndex: "totalAmountWithTax",
|
||||
key: "totalAmountWithTax",
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
title: "备注",
|
||||
dataIndex: "remark"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "action",
|
||||
key: "action",
|
||||
fixed: "right"
|
||||
}
|
||||
]);
|
||||
|
||||
const dataList = ref<LendingSettle[]>([]);
|
||||
|
||||
const changeDate = (data, index) => {
|
||||
if (dataList.value[index].startDate && dataList.value[index].stopDate) {
|
||||
dataList.value[index].calDay = dayjs(dataList.value[index].stopDate).diff(dayjs(dataList.value[index].startDate), "day");
|
||||
if (dataList.value[index].daysInMonth && dataList.value[index].monthRentAmount) {
|
||||
dataList.value[index].dailyRentAmount = (dataList.value[index].monthRentAmount / dataList.value[index].daysInMonth).toFixed(8);
|
||||
dataList.value[index].shouldPayRentAmount = dataList.value[index].dailyRentAmount * dataList.value[index].calDay;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const changeTotalAmount = () => {
|
||||
let total = 0;
|
||||
dataList.value.forEach(item => {
|
||||
total += parseFloat(item.totalAmountWithTax);
|
||||
});
|
||||
emits("total", total);
|
||||
};
|
||||
|
||||
const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
defineExpose({ dataList });
|
||||
</script>
|
||||
258
src/views/tower/lending/index.vue
Normal file
258
src/views/tower/lending/index.vue
Normal file
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="invoicingId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 800 }"
|
||||
class="sys-org-table"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
@batchMove="openMove"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'createTime'">
|
||||
<a-tooltip :title="`${toDateString(record.createTime)}`">
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="确定要删除此记录吗?"
|
||||
@confirm="remove(record)"
|
||||
>
|
||||
<a class="ele-text-danger">删除</a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<Edit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
<!-- 合同详情弹窗 -->
|
||||
<Info v-model:visible="showInfo" :data="current" @done="reload" />
|
||||
<!-- 批量转移弹窗 -->
|
||||
<!-- <CustomerMove v-model:visible="showMove" :data="selection" @done="batchMove" />-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, createVNode, ref } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import {
|
||||
ExclamationCircleOutlined,
|
||||
UserOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import type { EleProTable } from 'ele-admin-pro';
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { toDateString } from 'ele-admin-pro';
|
||||
import Search from './components/search.vue';
|
||||
import Edit from './components/edit.vue';
|
||||
import Info from './components/info.vue';
|
||||
import { timeAgo } from 'ele-admin-pro';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { Lending, LendingParam } from "@/api/tower/lending/model";
|
||||
import { pageLending, removeBatchLending, removeLending } from "@/api/tower/lending";
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
const loginUser = computed(() => userStore.info ?? {});
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<Lending[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<Lending | null>(null);
|
||||
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 是否显示批量移动弹窗
|
||||
const showMove = ref(false);
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
if (filters) {
|
||||
where.status = filters.status;
|
||||
}
|
||||
return pageLending({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: 'index',
|
||||
width: 48,
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: '项目名称',
|
||||
dataIndex: 'projectName',
|
||||
},
|
||||
{
|
||||
title: '合同编号',
|
||||
dataIndex: 'contactNumber'
|
||||
},
|
||||
{
|
||||
title: '结算日期',
|
||||
dataIndex: 'settleDate',
|
||||
},
|
||||
{
|
||||
title: '产权单位',
|
||||
dataIndex: 'propertyCompany'
|
||||
},
|
||||
{
|
||||
title: '本期结算金额',
|
||||
dataIndex: 'settleAmount'
|
||||
},
|
||||
{
|
||||
title: '税金',
|
||||
dataIndex: 'taxAmount'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
align: 'center',
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: LendingParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Lending) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
|
||||
const showSettle = ref<Boolean>(false)
|
||||
const openSettle = (row?: Lending) => {
|
||||
current.value = row ?? null;
|
||||
showSettle.value = true;
|
||||
};
|
||||
|
||||
/* 打开批量移动弹窗 */
|
||||
const openMove = () => {
|
||||
showMove.value = true;
|
||||
};
|
||||
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row?: Lending) => {
|
||||
current.value = row ?? null;
|
||||
showInfo.value = true;
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: Lending) => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
removeLending(row.lendingId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量转移 */
|
||||
const batchMove = (userId) => {
|
||||
console.log(userId, '批量转移0000');
|
||||
console.log(selection.value);
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要删除选中的记录吗?',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
removeBatchLending(
|
||||
selection.value.map((d) => {
|
||||
if (loginUser.value.userId === d.userId) {
|
||||
return d.lendingId;
|
||||
}
|
||||
})
|
||||
)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Accessory'
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -96,7 +96,7 @@
|
||||
title: '设备状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
customRender: ({ text }) => ['闲置', '报废', '注销', '转卖'][text]
|
||||
customRender: ({ text }) => ['闲置', '报废', '注销', '转卖', '在用', '场地'][text]
|
||||
},
|
||||
{
|
||||
title: '设备名称',
|
||||
|
||||
@@ -1,268 +1,302 @@
|
||||
<template>
|
||||
<a-spin :spinning="loading">
|
||||
<a-button type="primary" style="margin-bottom: 10px" @click="add">
|
||||
<span>添加</span>
|
||||
</a-button>
|
||||
<a-table
|
||||
size="middle"
|
||||
row-key="projectOrderId"
|
||||
:pagination="false"
|
||||
:data-source="list"
|
||||
:columns="columns"
|
||||
>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'equipmentName'">
|
||||
<TowerSelectModel
|
||||
v-if="record.isEdit"
|
||||
:placeholder="`请选择设备名称`"
|
||||
v-model:value="record.equipmentName"
|
||||
:index="index"
|
||||
@done="chooseEquipmentName"
|
||||
/>
|
||||
<div v-else>{{ record.equipmentName }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'equipmentModel'">
|
||||
<TowerSelectModel
|
||||
v-if="record.isEdit"
|
||||
:placeholder="`请选择设备型号`"
|
||||
v-model:value="record.equipmentModel"
|
||||
@done="chooseEquipmentModel"
|
||||
/>
|
||||
<div v-else>{{ record.equipmentModel }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'equipmentNum'">
|
||||
<a-input
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.equipmentNum"
|
||||
placeholder="请输入预定数量"
|
||||
/>
|
||||
<div v-else>{{ record.equipmentNum }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'unit'">
|
||||
<a-input
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.unit"
|
||||
placeholder="请输入单位"
|
||||
/>
|
||||
<div v-else>{{ record.unit }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'startTime'">
|
||||
<a-date-picker
|
||||
v-if="record.isEdit"
|
||||
placeholder="预计进场时间"
|
||||
value-format="YYYY-MM-DD"
|
||||
v-model:value="record.startTime"
|
||||
/>
|
||||
<div v-else>{{ record.startTime }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'endTime'">
|
||||
<a-date-picker
|
||||
v-if="record.isEdit"
|
||||
placeholder="预计退场时间"
|
||||
value-format="YYYY-MM-DD"
|
||||
v-model:value="record.endTime"
|
||||
/>
|
||||
<div v-else>{{ record.endTime }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'year'">
|
||||
<a-input-number
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.year"
|
||||
placeholder="出厂年限"
|
||||
/>
|
||||
<div v-else>{{ record.year }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'documenter'">
|
||||
<SelectStaff
|
||||
v-if="record.isEdit"
|
||||
:placeholder="`对应资料员`"
|
||||
:index="index"
|
||||
v-model:value="record.documenter"
|
||||
@done="chooseDocumenter"
|
||||
/>
|
||||
<div v-else>{{ record.documenter }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'comments'">
|
||||
<a-input
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.comments"
|
||||
placeholder="备注"
|
||||
/>
|
||||
<div v-else>{{ record.comments }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a v-if="record.isEdit" @click="done(record, index)">完成</a>
|
||||
<a v-else @click="edit(record, index)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="确定要删除此记录吗?"
|
||||
@confirm="remove(record, index)"
|
||||
>
|
||||
<a class="ele-text-danger">删除</a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-spin>
|
||||
<a-spin :spinning="loading">
|
||||
<a-button type="primary" style="margin-bottom: 10px" @click="add" :disabled="placeList?.length === 0">
|
||||
<span>添加</span>
|
||||
</a-button>
|
||||
<p style="color: red" v-if="placeList?.length === 0">请先添加标地</p>
|
||||
<a-table
|
||||
size="middle"
|
||||
row-key="projectOrderId"
|
||||
:pagination="false"
|
||||
:data-source="list"
|
||||
:columns="columns"
|
||||
>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'equipmentName'">
|
||||
<TowerEquipmentModel
|
||||
v-if="record.isEdit"
|
||||
:placeholder="`请选择设备`"
|
||||
v-model:value="record.equipmentName"
|
||||
:index="index"
|
||||
idle-only
|
||||
@done="chooseEquipmentName($event, index)"
|
||||
/>
|
||||
<div v-else>{{ record.equipmentName }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'equipmentModel'">
|
||||
<a-input
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.equipmentModel"
|
||||
placeholder="设备型号"
|
||||
readonly
|
||||
/>
|
||||
<div v-else>{{ record.equipmentModel }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'factoryNo'">
|
||||
<a-input
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.factoryNo"
|
||||
placeholder="出厂编号"
|
||||
readonly
|
||||
/>
|
||||
<div v-else>{{ record.factoryNo }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'filingNo'">
|
||||
<a-input
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.filingNo"
|
||||
placeholder="备案编号"
|
||||
readonly
|
||||
/>
|
||||
<div v-else>{{ record.filingNo }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'equipmentNum'">
|
||||
<a-input
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.equipmentNum"
|
||||
placeholder="请输入预定数量"
|
||||
/>
|
||||
<div v-else>{{ record.equipmentNum }}</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.key === 'unit'">
|
||||
<a-input
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.unit"
|
||||
placeholder="请输入单位"
|
||||
/>
|
||||
<div v-else>{{ record.unit }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'startTime'">
|
||||
<a-date-picker
|
||||
v-if="record.isEdit"
|
||||
placeholder="开工时间"
|
||||
value-format="YYYY-MM-DD"
|
||||
v-model:value="record.startTime"
|
||||
/>
|
||||
<div v-else>{{ record.startTime }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'endTime'">
|
||||
<a-date-picker
|
||||
v-if="record.isEdit"
|
||||
placeholder="停工时间"
|
||||
value-format="YYYY-MM-DD"
|
||||
v-model:value="record.endTime"
|
||||
/>
|
||||
<div v-else>{{ record.endTime }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'year'">
|
||||
<a-input-number
|
||||
v-if="record.isEdit"
|
||||
v-model:value="record.year"
|
||||
placeholder="出厂年限"
|
||||
/>
|
||||
<div v-else>{{ record.year }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'documenter'">
|
||||
<SelectStaff
|
||||
v-if="record.isEdit"
|
||||
:placeholder="`对应资料员`"
|
||||
:index="index"
|
||||
v-model:value="record.documenter"
|
||||
@done="chooseDocumenter"
|
||||
/>
|
||||
<div v-else>{{ record.documenter }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'comments'">
|
||||
<a-select v-if="record.isEdit" v-model:value="record.comments" placeholder="请选择标地">
|
||||
<a-select-option :value="item" v-for="(item, index) in placeList" :key="index">{{ item }}</a-select-option>
|
||||
</a-select>
|
||||
<div v-else>{{ record.comments }}</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a v-if="record.isEdit" @click="done(record, index)">完成</a>
|
||||
<a v-else @click="edit(record, index)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a-popconfirm
|
||||
title="确定要删除此记录吗?"
|
||||
@confirm="remove(record, index)"
|
||||
>
|
||||
<a class="ele-text-danger">删除</a>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { uuid } from 'ele-admin-pro/es';
|
||||
import type { ColumnsType } from 'ant-design-vue/es/table';
|
||||
import { ProjectOrder } from '@/api/tower/project/order/model';
|
||||
import { removeProjectOrder } from '@/api/tower/project/order';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { uuid } from "ele-admin-pro/es";
|
||||
import type { ColumnsType } from "ant-design-vue/es/table";
|
||||
import { ProjectOrder } from "@/api/tower/project/order/model";
|
||||
import { removeProjectOrder } from "@/api/tower/project/order";
|
||||
import { message } from "ant-design-vue";
|
||||
import { TowerEquipment } from "@/api/tower/equipment/model";
|
||||
|
||||
const props = withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
value?: ProjectOrder[];
|
||||
projectId?: number;
|
||||
placeholder?: string;
|
||||
value?: ProjectOrder[];
|
||||
projectId?: number;
|
||||
placeholder?: string;
|
||||
placeList?: string[];
|
||||
}>(),
|
||||
{
|
||||
placeholder: '请选择数据'
|
||||
placeholder: "请选择数据"
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
// 已添加成员
|
||||
const list = ref<ProjectOrder[]>([]);
|
||||
// 请求状态
|
||||
const loading = ref(false);
|
||||
// 已添加成员
|
||||
const list = ref<ProjectOrder[]>([]);
|
||||
// 请求状态
|
||||
const loading = ref(false);
|
||||
|
||||
// 列
|
||||
const columns = reactive<ColumnsType>([
|
||||
// 列
|
||||
const columns = reactive<ColumnsType>([
|
||||
{
|
||||
key: 'index',
|
||||
align: 'center',
|
||||
width: 30,
|
||||
customRender: ({ index }) => index + 1,
|
||||
fixed: 'left'
|
||||
key: "index",
|
||||
align: "center",
|
||||
width: 30,
|
||||
customRender: ({ index }) => index + 1,
|
||||
fixed: "left"
|
||||
},
|
||||
{
|
||||
title: '设备名称',
|
||||
align: 'center',
|
||||
dataIndex: 'equipmentName',
|
||||
key: 'equipmentName'
|
||||
title: "具体标地",
|
||||
align: "center",
|
||||
dataIndex: "comments",
|
||||
key: "comments"
|
||||
},
|
||||
{
|
||||
title: '规格型号',
|
||||
align: 'center',
|
||||
dataIndex: 'equipmentModel',
|
||||
key: 'equipmentModel'
|
||||
title: "设备名称",
|
||||
align: "center",
|
||||
dataIndex: "equipmentName",
|
||||
key: "equipmentName"
|
||||
},
|
||||
{
|
||||
title: '签订数量',
|
||||
align: 'center',
|
||||
dataIndex: 'equipmentNum',
|
||||
key: 'equipmentNum',
|
||||
width: 80
|
||||
title: "出厂编号",
|
||||
align: "center",
|
||||
dataIndex: "factoryNo",
|
||||
key: "factoryNo"
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
align: 'center',
|
||||
dataIndex: 'unit',
|
||||
key: 'unit',
|
||||
width: 60
|
||||
title: "规格型号",
|
||||
align: "center",
|
||||
dataIndex: "equipmentModel",
|
||||
key: "equipmentModel",
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '预计进场时间',
|
||||
align: 'center',
|
||||
dataIndex: 'startTime',
|
||||
key: 'startTime'
|
||||
title: "备案编号",
|
||||
align: "center",
|
||||
dataIndex: "filingNo",
|
||||
key: "filingNo",
|
||||
width: 200
|
||||
},
|
||||
// {
|
||||
// title: '签订数量',
|
||||
// align: 'center',
|
||||
// dataIndex: 'equipmentNum',
|
||||
// key: 'equipmentNum',
|
||||
// width: 80
|
||||
// },
|
||||
// {
|
||||
// title: '单位',
|
||||
// align: 'center',
|
||||
// dataIndex: 'unit',
|
||||
// key: 'unit',
|
||||
// width: 100
|
||||
// },
|
||||
{
|
||||
title: "开工时间",
|
||||
align: "center",
|
||||
dataIndex: "startTime",
|
||||
key: "startTime"
|
||||
},
|
||||
{
|
||||
title: '预计退场时间',
|
||||
align: 'center',
|
||||
dataIndex: 'endTime',
|
||||
key: 'endTime'
|
||||
title: "停工时间",
|
||||
align: "center",
|
||||
dataIndex: "endTime",
|
||||
key: "endTime"
|
||||
},
|
||||
{
|
||||
title: '出厂年限',
|
||||
align: 'center',
|
||||
dataIndex: 'year',
|
||||
key: 'year',
|
||||
width: 80
|
||||
title: "出厂年限",
|
||||
align: "center",
|
||||
dataIndex: "year",
|
||||
key: "year",
|
||||
width: 80
|
||||
},
|
||||
// {
|
||||
// title: '对应资料员',
|
||||
// align: 'center',
|
||||
// dataIndex: 'documenter',
|
||||
// key: 'documenter'
|
||||
// },
|
||||
{
|
||||
title: '对应资料员',
|
||||
align: 'center',
|
||||
dataIndex: 'documenter',
|
||||
key: 'documenter'
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
align: 'center',
|
||||
dataIndex: 'comments',
|
||||
key: 'comments'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
width: 100
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 100
|
||||
}
|
||||
]);
|
||||
]);
|
||||
|
||||
/* 添加 */
|
||||
const add = () => {
|
||||
/* 添加 */
|
||||
const add = () => {
|
||||
list.value.push({
|
||||
projectId: props.projectId,
|
||||
key: uuid(8),
|
||||
isEdit: true,
|
||||
equipmentNum: 1,
|
||||
unit: '台',
|
||||
startTime: undefined,
|
||||
endTime: undefined,
|
||||
year: undefined,
|
||||
documenter: undefined,
|
||||
comments: undefined
|
||||
projectId: props.projectId,
|
||||
key: uuid(8),
|
||||
isEdit: true,
|
||||
equipmentNum: 1,
|
||||
filingNo: undefined,
|
||||
unit: "台",
|
||||
startTime: undefined,
|
||||
endTime: undefined,
|
||||
year: undefined,
|
||||
documenter: undefined,
|
||||
comments: undefined
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const chooseEquipmentName = (data) => {
|
||||
list.value[data.index].equipmentName = data.name;
|
||||
list.value[data.index].equipmentModel = data.model;
|
||||
list.value[data.index].year = data.yearLife;
|
||||
};
|
||||
const chooseEquipmentName = (data: TowerEquipment, index: number) => {
|
||||
if (list.value.find((row) => row.equipmentId === data.equipmentId && !row.endTime)) return message.error('该设备已存在')
|
||||
list.value[index].equipmentId = data.equipmentId;
|
||||
list.value[index].equipmentName = data.name;
|
||||
list.value[index].equipmentModel = data.model;
|
||||
list.value[index].year = data.lifeYear;
|
||||
list.value[index].filingNo = data.filingNo;
|
||||
list.value[index].factoryNo = data.factoryNo;
|
||||
};
|
||||
|
||||
const chooseEquipmentModel = (data) => {
|
||||
list.value[data.index].equipmentName = data.name;
|
||||
list.value[data.index].equipmentModel = data.model;
|
||||
list.value[data.index].year = data.yearLife;
|
||||
};
|
||||
|
||||
const chooseDocumenter = (data) => {
|
||||
const chooseDocumenter = (data) => {
|
||||
list.value[data.index].documenter = data.nickname;
|
||||
};
|
||||
};
|
||||
|
||||
/* 编辑 */
|
||||
const edit = (_row: any, index: number) => {
|
||||
/* 编辑 */
|
||||
const edit = (_row: any, index: number) => {
|
||||
list.value[index].isEdit = true;
|
||||
};
|
||||
};
|
||||
|
||||
/* 完成编辑 */
|
||||
const done = (_row: any, index: number) => {
|
||||
/* 完成编辑 */
|
||||
const done = (_row: any, index: number) => {
|
||||
list.value[index].isEdit = false;
|
||||
};
|
||||
};
|
||||
|
||||
/* 删除 */
|
||||
const remove = (_row: any, index: number) => {
|
||||
/* 删除 */
|
||||
const remove = (_row: any, index: number) => {
|
||||
removeProjectOrder(_row.projectOrderId).then((msg) => {
|
||||
message.success(msg);
|
||||
message.success(msg);
|
||||
});
|
||||
list.value.splice(index, 1);
|
||||
};
|
||||
};
|
||||
|
||||
watch(
|
||||
watch(
|
||||
() => props.value,
|
||||
(value) => {
|
||||
if (value) {
|
||||
list.value = value;
|
||||
}
|
||||
if (value) {
|
||||
list.value = value;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
);
|
||||
</script>
|
||||
|
||||
102
src/views/tower/project/components/import.vue
Normal file
102
src/views/tower/project/components/import.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
:width="600"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
:title="`导入项目`"
|
||||
:body-style="{ paddingBottom: '28px' }"
|
||||
@update:visible="updateVisible"
|
||||
:footer="null"
|
||||
>
|
||||
<a-upload-dragger
|
||||
name="file"
|
||||
:show-upload-list="false"
|
||||
accept=".xls,.xlsx"
|
||||
:before-upload="handleImport"
|
||||
>
|
||||
<p class="ant-upload-drag-icon">
|
||||
<InboxOutlined />
|
||||
</p>
|
||||
<p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
|
||||
<p class="ant-upload-hint" style="max-width: 550px">
|
||||
提示:附件上传中,请不要做任何操作! 支持的文件类型为*.xls, *.xlsx!
|
||||
</p>
|
||||
</a-upload-dragger>
|
||||
<div style="margin: 20px auto; display: flex; justify-content: center">
|
||||
<a
|
||||
href="http://1.14.159.185:10042/template/project_template_0.xlsx"
|
||||
target="_blank"
|
||||
>下载项目导入模板</a>
|
||||
</div>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { InboxOutlined } from "@ant-design/icons-vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import { addBatchTowerEquipment } from "@/api/tower/equipment";
|
||||
import { TowerEquipment } from "@/api/tower/equipment/model";
|
||||
import { read, utils } from "xlsx";
|
||||
import { ref } from "vue";
|
||||
import { Project } from "@/api/tower/project/model";
|
||||
import { addBatchProject } from "@/api/tower/project";
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 导入的数据
|
||||
const importData = ref<Project[]>([]);
|
||||
const handleImport = (file: File) => {
|
||||
if (
|
||||
![
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
].includes(file.type)
|
||||
) {
|
||||
message.error("只能选择 excel 文件");
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
message.error("大小不能超过 20MB");
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
importData.value = [];
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target?.result as any);
|
||||
const workbook = read(data, { type: "array" });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json<string[]>(worksheet, { header: 1 });
|
||||
aoa.slice(1).map((d) => {
|
||||
if (d[0]) {
|
||||
importData.value.push({
|
||||
projectName: d[0],
|
||||
securityStatus: d[1],
|
||||
projectCity: d[2],
|
||||
competentDepartment: d[3],
|
||||
companyName: d[4],
|
||||
customerName: d[5],
|
||||
projectStatus: "未开工"
|
||||
});
|
||||
}
|
||||
});
|
||||
addBatchProject(importData.value).then(() => {
|
||||
message.success("导入成功");
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
};
|
||||
</script>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
<span>批量删除</span>
|
||||
</a-button>
|
||||
<a-button class="ele-btn-icon">
|
||||
<a-button class="ele-btn-icon" @click.native="openImport">
|
||||
<span>导入项目</span>
|
||||
</a-button>
|
||||
<a-button class="ele-btn-icon">
|
||||
@@ -36,6 +36,7 @@
|
||||
@search="search"
|
||||
/>
|
||||
</a-space>
|
||||
<Import v-model:visible="showImport" @done="search" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -43,6 +44,7 @@
|
||||
import useSearch from '@/utils/use-search';
|
||||
import { ref, watch } from 'vue';
|
||||
import { OrderParam } from '@/api/order/model';
|
||||
import Import from "@/views/tower/project/components/import.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -97,6 +99,11 @@
|
||||
emit('remove');
|
||||
};
|
||||
|
||||
const showImport = ref<Boolean>(false)
|
||||
const openImport = () => {
|
||||
showImport.value = true;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.selection,
|
||||
() => {}
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
:columns="columns"
|
||||
>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'role'">
|
||||
<a-tag color="green" v-if="record.role === 10">可见成员</a-tag>
|
||||
<a-tag color="orange" v-if="record.role === 20">项目联系人</a-tag>
|
||||
<template v-if="column.key === 'level'">
|
||||
<a-tag color="orange" v-if="record.user && record.user.userLevel">{{ USER_LEVEL_LIST[record.user.userLevel] }}</a-tag>
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
@@ -34,7 +33,7 @@
|
||||
import type { ColumnsType } from 'ant-design-vue/es/table';
|
||||
import { ProjectUser } from '@/api/tower/project/user/model';
|
||||
import { removeProjectUser } from '@/api/tower/project/user';
|
||||
import { User } from '@/api/system/user/model';
|
||||
import { User, USER_LEVEL_LIST } from "@/api/system/user/model";
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
const props = withDefaults(
|
||||
@@ -65,8 +64,7 @@
|
||||
{
|
||||
title: '类型',
|
||||
align: 'center',
|
||||
dataIndex: 'role',
|
||||
key: 'role'
|
||||
key: 'level'
|
||||
},
|
||||
{
|
||||
title: '所在部门',
|
||||
|
||||
@@ -1,288 +1,328 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false">
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="projectId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
:customRow="customRow"
|
||||
:height="tableHeight"
|
||||
:full-height="fixedHeight ? 'calc(100vh - 100px)' : void 0"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 1200 }"
|
||||
class="sys-org-table"
|
||||
:striped="true"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'nickname'">
|
||||
{{ record.nickname }}
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
{{ record.createTime }}
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="openEdit(record)">库存查看</a>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
<div>
|
||||
<a-card title="项目数据">
|
||||
<a-row :gutter="10">
|
||||
<a-col :span="4">
|
||||
<span>项目总数:{{ projectData.totalNum }}</span>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<span>已开工总数:{{ projectData.startedNum }}</span>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<span>未开工:{{ projectData.notStartNum }}</span>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
<div class="page">
|
||||
<div class="ele-body">
|
||||
<a-card :bordered="false">
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="projectId"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
v-model:selection="selection"
|
||||
:customRow="customRow"
|
||||
:height="tableHeight"
|
||||
:full-height="fixedHeight ? 'calc(100vh - 100px)' : void 0"
|
||||
tool-class="ele-toolbar-form"
|
||||
:scroll="{ x: 1200 }"
|
||||
class="sys-org-table"
|
||||
:striped="true"
|
||||
>
|
||||
<template #toolbar>
|
||||
<search
|
||||
@search="reload"
|
||||
:selection="selection"
|
||||
@add="openEdit"
|
||||
@remove="removeBatch"
|
||||
/>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'nickname'">
|
||||
{{ record.nickname }}
|
||||
</template>
|
||||
<template v-if="column.key === 'orders'">
|
||||
{{ record.orders.length > 0 ? record.orders[0].comments : "" }}
|
||||
</template>
|
||||
<template v-if="column.key === 'createTime'">
|
||||
{{ record.createTime }}
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="openEdit(record)">库存查看</a>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
</div>
|
||||
<!-- 编辑弹窗 -->
|
||||
<ProjectEdit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
<!-- 订单详情 -->
|
||||
<order-info v-model:visible="showInfo" :data="current" @done="reload" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 编辑弹窗 -->
|
||||
<ProjectEdit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
<!-- 订单详情 -->
|
||||
<order-info v-model:visible="showInfo" :data="current" @done="reload" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { createVNode, computed, ref } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import type { EleProTable } from 'ele-admin-pro';
|
||||
import type {
|
||||
import { createVNode, computed, ref, reactive } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
|
||||
import type { EleProTable } from "ele-admin-pro";
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import Search from './components/search.vue';
|
||||
import ProjectEdit from './components/project-edit.vue';
|
||||
import OrderInfo from './components/order-info.vue';
|
||||
import {
|
||||
} from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import Search from "./components/search.vue";
|
||||
import ProjectEdit from "./components/project-edit.vue";
|
||||
import OrderInfo from "./components/order-info.vue";
|
||||
import {
|
||||
pageProject,
|
||||
removeBatchProject,
|
||||
removeProject
|
||||
} from '@/api/tower/project';
|
||||
import { Project, ProjectParam } from '@/api/tower/project/model';
|
||||
removeProject, towerProjectData
|
||||
} from "@/api/tower/project";
|
||||
import { Project, ProjectParam } from "@/api/tower/project/model";
|
||||
import { towerEquipmentData } from "@/api/tower/equipment";
|
||||
|
||||
defineProps<{
|
||||
defineProps<{
|
||||
activeKey?: boolean;
|
||||
data?: any;
|
||||
}>();
|
||||
}>();
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
key: 'index',
|
||||
width: 48,
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
key: "index",
|
||||
width: 48,
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: '项目状态',
|
||||
dataIndex: 'projectStatus',
|
||||
key: 'projectStatus'
|
||||
title: "项目状态",
|
||||
dataIndex: "projectStatus",
|
||||
key: "projectStatus"
|
||||
},
|
||||
{
|
||||
title: '项目名称',
|
||||
dataIndex: 'projectName',
|
||||
key: 'projectName'
|
||||
title: "项目名称",
|
||||
dataIndex: "projectName",
|
||||
key: "projectName"
|
||||
},
|
||||
// {
|
||||
// title: '具体标地',
|
||||
// // dataIndex: 'projectCity',
|
||||
// key: 'orders'
|
||||
// },
|
||||
{
|
||||
title: "承租单位",
|
||||
dataIndex: "customerName",
|
||||
key: "customerName"
|
||||
},
|
||||
{
|
||||
title: '项目地址',
|
||||
dataIndex: 'projectAddress',
|
||||
key: 'projectAddress'
|
||||
title: "项目所属主管部门",
|
||||
dataIndex: "competentDepartment"
|
||||
},
|
||||
{
|
||||
title: '承租单位',
|
||||
dataIndex: 'customerName',
|
||||
key: 'customerName'
|
||||
title: "关联设备数",
|
||||
dataIndex: "equipmentNum"
|
||||
},
|
||||
{
|
||||
title: '项目负责人',
|
||||
dataIndex: 'director',
|
||||
key: 'director'
|
||||
title: "项目管理员",
|
||||
dataIndex: "director"
|
||||
},
|
||||
// {
|
||||
// title: '检查次数',
|
||||
// dataIndex: 'companyId',
|
||||
// key: 'companyId'
|
||||
// },
|
||||
// {
|
||||
// title: '保养次数',
|
||||
// dataIndex: 'companyId',
|
||||
// key: 'companyId'
|
||||
// },
|
||||
{
|
||||
title: "创建时间",
|
||||
dataIndex: "createTime"
|
||||
},
|
||||
{
|
||||
title: '是否关联',
|
||||
dataIndex: 'companyId',
|
||||
key: 'companyId'
|
||||
},
|
||||
{
|
||||
title: '检查频率',
|
||||
dataIndex: 'companyId',
|
||||
key: 'companyId'
|
||||
},
|
||||
{
|
||||
title: '保养频率',
|
||||
dataIndex: 'companyId',
|
||||
key: 'companyId'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
hideInSetting: true
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 150,
|
||||
align: "center",
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
]);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<Project[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<Project | null>(null);
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 表格固定高度
|
||||
const fixedHeight = ref(true);
|
||||
// 表格高度
|
||||
const tableHeight = computed(() => {
|
||||
return fixedHeight.value ? 'calc(100vh - 308px)' : void 0;
|
||||
});
|
||||
// 表格选中数据
|
||||
const selection = ref<Project[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<Project | null>(null);
|
||||
// 是否显示资产详情
|
||||
const showInfo = ref(false);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 表格固定高度
|
||||
const fixedHeight = ref(true);
|
||||
// 表格高度
|
||||
const tableHeight = computed(() => {
|
||||
return fixedHeight.value ? "calc(100vh - 308px)" : void 0;
|
||||
});
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
// 搜索条件
|
||||
if (filters.payMethod) {
|
||||
where.payMethod = filters.payMethod;
|
||||
where.payMethod = filters.payMethod;
|
||||
}
|
||||
if (filters.deliveryType) {
|
||||
where.deliveryType = filters.deliveryType;
|
||||
where.deliveryType = filters.deliveryType;
|
||||
}
|
||||
if (filters.payStatus) {
|
||||
where.payStatus = filters.payStatus;
|
||||
where.payStatus = filters.payStatus;
|
||||
}
|
||||
if (filters.orderSource) {
|
||||
where.orderSource = filters.orderSource;
|
||||
where.orderSource = filters.orderSource;
|
||||
}
|
||||
where.tenantId = localStorage.getItem('tenantId');
|
||||
where.tenantId = localStorage.getItem("tenantId");
|
||||
where.payStatus = 20;
|
||||
return pageProject({
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
...where,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: ProjectParam) => {
|
||||
/* 搜索 */
|
||||
const reload = (where?: ProjectParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
getData();
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Project) => {
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: Project) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
};
|
||||
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row?: Project) => {
|
||||
/* 打开用户详情弹窗 */
|
||||
const openInfo = (row?: Project) => {
|
||||
current.value = row ?? null;
|
||||
showInfo.value = true;
|
||||
};
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: Project) => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
|
||||
let projectData = reactive({
|
||||
totalNum: 0,
|
||||
startedNum: 0,
|
||||
notStartNum: 0
|
||||
});
|
||||
const getData = async () => {
|
||||
const res = await towerProjectData();
|
||||
for (let key in projectData) projectData[key] = res[key];
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: Project) => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeProject(row.projectId)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
console.log(selection.value);
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要删除选中的记录吗?',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading('请求中..', 0);
|
||||
removeBatchProject(selection.value.map((d) => d.projectId))
|
||||
.then((msg) => {
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
console.log(selection.value);
|
||||
if (!selection.value.length) {
|
||||
message.error("请至少选择一条数据");
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: "确定要删除选中的记录吗?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
onOk: () => {
|
||||
const hide = message.loading("请求中..", 0);
|
||||
removeBatchProject(selection.value.map((d) => d.projectId))
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: Project) => {
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: Project) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
}
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
reload();
|
||||
reload();
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'ProjectIndex'
|
||||
};
|
||||
export default {
|
||||
name: "ProjectIndex"
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
p {
|
||||
p {
|
||||
line-height: 0.8;
|
||||
}
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-body) {
|
||||
overflow: auto !important;
|
||||
overflow: overlay !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
.sys-org-table :deep(.ant-table-pagination.ant-pagination) {
|
||||
padding: 0 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.price-edit {
|
||||
}
|
||||
|
||||
.price-edit {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.comments {
|
||||
}
|
||||
|
||||
.comments {
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -22,27 +22,60 @@
|
||||
@ok="changeDate($event, index)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'inDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择实际进场日期"
|
||||
v-model:value="record.inDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'outDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择实际出场日期"
|
||||
v-model:value="record.outDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'settleCycle'">
|
||||
<span v-if="record.startDate && record.endDate">
|
||||
{{ Math.floor(record.days / 30) }}月
|
||||
{{ record.days - (Math.floor(record.days / 30) * 30) }}天
|
||||
</span>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-input v-model:value="record.month" type="number">
|
||||
<template #addonAfter>月</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-input v-model:value="record.day" type="number">
|
||||
<template #addonAfter>日</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<template v-if="column.key === 'monthAmount'">
|
||||
<a-input v-model:value="record.monthAmount" type="number" @change="changeDate($event, index)" />
|
||||
</template>
|
||||
<template v-if="column.key === 'dailyAmount'">
|
||||
<span v-if="record.monthAmount">{{ record.dailyAmount }}</span>
|
||||
<a-input v-model:value="record.dailyAmount" type="number" />
|
||||
</template>
|
||||
<template v-if="column.key === 'payRate'">
|
||||
<a-input v-model:value="record.payRate" type="number">
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithTax'">
|
||||
<span v-if="record.monthAmount">{{ (record.dailyAmount * record.days).toFixed(2) }}</span>
|
||||
<span
|
||||
v-if="record.monthAmount">{{ ((record.dailyAmount * record.day + record.monthAmount * record.month) * record.payRate / 100).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'tax'">
|
||||
<span v-if="record.monthAmount">{{ (record.dailyAmount * record.days * (record.taxRate / 100)).toFixed(2) }}</span>
|
||||
<span
|
||||
v-if="record.monthAmount">{{ (((record.dailyAmount * record.day + record.monthAmount * record.month) * record.payRate / 100) * (record.taxRate / 100)).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithoutTax'">
|
||||
<span
|
||||
v-if="record.monthAmount">{{ ((record.dailyAmount * record.days) - (record.dailyAmount * record.days * (record.taxRate / 100))).toFixed(2)
|
||||
v-if="record.monthAmount">{{ ((1 - (record.taxRate / 100)) * ((record.dailyAmount * record.day + record.monthAmount * record.month) * record.payRate / 100)).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'remark'">
|
||||
@@ -55,11 +88,38 @@
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<template #summary>
|
||||
<a-table-summary-row>
|
||||
<a-table-summary-cell>合计</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.tax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithoutTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
</a-table-summary-row>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { computed, onMounted, ref, watch } from "vue";
|
||||
import { SettleDetail } from "@/api/tower/settleDetail/model";
|
||||
import { ColumnItem } from "ele-admin-pro/es/ele-pro-table/types";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
@@ -108,6 +168,16 @@ const columns = ref<ColumnItem[]>([
|
||||
dataIndex: "endDate",
|
||||
key: "endDate"
|
||||
},
|
||||
// {
|
||||
// title: "实际进场日期",
|
||||
// dataIndex: "inDate",
|
||||
// key: "inDate"
|
||||
// },
|
||||
// {
|
||||
// title: "实际出场日期",
|
||||
// dataIndex: "outDate",
|
||||
// key: "outDate"
|
||||
// },
|
||||
{
|
||||
title: "实际结算周期",
|
||||
dataIndex: "settleCycle",
|
||||
@@ -124,7 +194,12 @@ const columns = ref<ColumnItem[]>([
|
||||
key: "dailyAmount"
|
||||
},
|
||||
{
|
||||
title: "本期租金含税金额(元)",
|
||||
title: "支付比例",
|
||||
dataIndex: "payRate",
|
||||
key: "payRate"
|
||||
},
|
||||
{
|
||||
title: "含税应付(元)",
|
||||
dataIndex: "amountWithTax",
|
||||
key: "amountWithTax"
|
||||
},
|
||||
@@ -154,8 +229,12 @@ const dataList = ref<SettleDetail[]>([]);
|
||||
|
||||
const changeDate = (data, index) => {
|
||||
if (dataList.value[index].startDate && dataList.value[index].endDate) {
|
||||
dataList.value[index].days = dayjs(dataList.value[index].endDate).diff(dayjs(dataList.value[index].startDate), "day");
|
||||
if (dataList.value[index].monthAmount) dataList.value[index].dailyAmount = (dataList.value[index].monthAmount / 30).toFixed(8);
|
||||
dataList.value[index].days = dayjs(dataList.value[index].endDate).diff(dayjs(dataList.value[index].startDate), "day") + 1;
|
||||
dataList.value[index].month = Math.floor(dataList.value[index].days / 30);
|
||||
dataList.value[index].day = dataList.value[index].days - (Math.floor(dataList.value[index].days / 30) * 30);
|
||||
if (dataList.value[index].monthAmount) {
|
||||
dataList.value[index].dailyAmount = (dataList.value[index].monthAmount / 30).toFixed(8);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -163,13 +242,38 @@ const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
dataList.value = props.dataSource;
|
||||
calTotals();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
calTotals();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
defineExpose({ dataList })
|
||||
const totals = ref({ amountWithTax: 0, tax: 0, amountWithoutTax: 0 });
|
||||
const calTotals = () => {
|
||||
let amountWithTax: number = 0;
|
||||
let tax = 0;
|
||||
let amountWithoutTax = 0;
|
||||
if (dataList.value && dataList.value.length > 0 && (dataList.value[0].taxRate !== undefined)) {
|
||||
const taxRate = dataList.value[0].taxRate;
|
||||
dataList.value.forEach(({ month, monthAmount, day, dailyAmount, payRate }) => {
|
||||
amountWithTax += (month * monthAmount + day * dailyAmount) * payRate / 100;
|
||||
});
|
||||
amountWithTax = Number(amountWithTax.toFixed(2));
|
||||
tax = amountWithTax * (taxRate / 100);
|
||||
tax = Number(tax.toFixed(2));
|
||||
amountWithoutTax = amountWithTax - tax;
|
||||
amountWithoutTax = Number(amountWithoutTax.toFixed(2));
|
||||
}
|
||||
totals.value = { amountWithTax, tax, amountWithoutTax };
|
||||
};
|
||||
|
||||
defineExpose({ dataList });
|
||||
</script>
|
||||
|
||||
@@ -5,24 +5,43 @@
|
||||
<template v-if="column.key === 'singleAmount'">
|
||||
<a-input v-model:value="record.singleAmount" type="number" />
|
||||
</template>
|
||||
<template v-if="column.key === 'inDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择实际进场日期"
|
||||
v-model:value="record.inDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'outDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择实际出场日期"
|
||||
v-model:value="record.outDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'num'">
|
||||
<a-input v-model:value="record.num" type="number" />
|
||||
</template>
|
||||
<template v-if="column.key === 'sumAmount'">
|
||||
<span v-if="record.singleAmount && record.num">
|
||||
{{ (record.singleAmount * record.num).toFixed(2) }}
|
||||
</span>
|
||||
<template v-if="column.key === 'payRate'">
|
||||
<a-input v-model:value="record.payRate" type="number">
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithTax'">
|
||||
<span v-if="record.singleAmount && record.num">{{ (record.singleAmount * record.num).toFixed(2) }}</span>
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ ((record.singleAmount * record.num) * record.payRate / 100).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'tax'">
|
||||
<span v-if="record.singleAmount && record.num">{{ (record.singleAmount * record.num * (record.taxRate / 100)).toFixed(2)
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ (((record.singleAmount * record.num) * record.payRate / 100) * (record.taxRate / 100)).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithoutTax'">
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ ((record.singleAmount * record.num) - (record.singleAmount * record.num * (record.taxRate / 100))).toFixed(2)
|
||||
v-if="record.singleAmount && record.num">{{ (((record.singleAmount * record.num) * record.payRate / 100) - (record.singleAmount * record.num * (record.taxRate / 100))).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'remark'">
|
||||
@@ -35,6 +54,30 @@
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<template #summary>
|
||||
<a-table-summary-row>
|
||||
<a-table-summary-cell>合计</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.tax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithoutTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
</a-table-summary-row>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
@@ -78,6 +121,16 @@ const columns = ref<ColumnItem[]>([
|
||||
dataIndex: "factoryNo",
|
||||
key: "factoryNo"
|
||||
},
|
||||
{
|
||||
title: "实际进场日期",
|
||||
dataIndex: "inDate",
|
||||
key: "inDate"
|
||||
},
|
||||
{
|
||||
title: "实际出场日期",
|
||||
dataIndex: "outDate",
|
||||
key: "outDate"
|
||||
},
|
||||
{
|
||||
title: "费用类型",
|
||||
dataIndex: "settleCostType",
|
||||
@@ -94,9 +147,9 @@ const columns = ref<ColumnItem[]>([
|
||||
key: "num"
|
||||
},
|
||||
{
|
||||
title: "进退场小计(元)",
|
||||
dataIndex: "sumAmount",
|
||||
key: "sumAmount"
|
||||
title: "支付比例",
|
||||
dataIndex: "payRate",
|
||||
key: "payRate"
|
||||
},
|
||||
{
|
||||
title: "含税金额(元)",
|
||||
@@ -129,17 +182,42 @@ const dataList = ref<SettleDetail[]>([]);
|
||||
|
||||
const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
calTotals();
|
||||
};
|
||||
|
||||
const totals = ref({ amountWithTax: 0, tax: 0, amountWithoutTax: 0 });
|
||||
const calTotals = () => {
|
||||
let amountWithTax = 0;
|
||||
let tax = 0;
|
||||
let amountWithoutTax = 0;
|
||||
if (dataList.value && dataList.value.length > 0 && (dataList.value[0].taxRate !== undefined)) {
|
||||
const taxRate = dataList.value[0].taxRate;
|
||||
dataList.value.forEach(({ singleAmount, num, payRate }) => {
|
||||
amountWithTax += singleAmount * num * payRate / 100;
|
||||
});
|
||||
amountWithTax = Number(amountWithTax.toFixed(2));
|
||||
tax = amountWithTax * (taxRate / 100);
|
||||
tax = Number(tax.toFixed(2));
|
||||
amountWithoutTax = amountWithTax - tax;
|
||||
amountWithoutTax = Number(amountWithoutTax.toFixed(2));
|
||||
}
|
||||
totals.value = { amountWithTax, tax, amountWithoutTax };
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
dataList.value = props.dataSource;
|
||||
calTotals();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
console.log(dataList.value)
|
||||
console.log(dataList.value);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
defineExpose({ dataList })
|
||||
defineExpose({ dataList });
|
||||
|
||||
</script>
|
||||
|
||||
@@ -23,26 +23,41 @@
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'settleCycle'">
|
||||
<span v-if="record.startDate && record.endDate">
|
||||
{{ Math.floor(record.days / 30) }}月
|
||||
{{ record.days - (Math.floor(record.days / 30) * 30) }}天
|
||||
</span>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-input v-model:value="record.month">
|
||||
<template #addonAfter>月</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-input v-model:value="record.day">
|
||||
<template #addonAfter>日</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<template v-if="column.key === 'monthAmount'">
|
||||
<a-input v-model:value="record.monthAmount" type="number" @change="changeDate($event, index)" />
|
||||
</template>
|
||||
<template v-if="column.key === 'dailyAmount'">
|
||||
<span v-if="record.monthAmount">{{ record.dailyAmount }}</span>
|
||||
<a-input v-model:value="record.dailyAmount" type="number" />
|
||||
</template>
|
||||
<template v-if="column.key === 'payRate'">
|
||||
<a-input v-model:value="record.payRate" type="number">
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithTax'">
|
||||
<span v-if="record.monthAmount">{{ (record.dailyAmount * record.days).toFixed(2) }}</span>
|
||||
<span v-if="record.monthAmount">{{ ((record.dailyAmount * record.days + record.monthAmount * record.month) * record.payRate / 100).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'tax'">
|
||||
<span v-if="record.monthAmount">{{ (record.dailyAmount * record.days * (record.taxRate / 100)).toFixed(2) }}</span>
|
||||
<span v-if="record.monthAmount">{{ (((record.dailyAmount * record.days + record.monthAmount * record.month) * record.payRate / 100) * (record.taxRate / 100)).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithoutTax'">
|
||||
<span
|
||||
v-if="record.monthAmount">{{ ((record.dailyAmount * record.days) - (record.dailyAmount * record.days * (record.taxRate / 100))).toFixed(2)
|
||||
v-if="record.monthAmount">{{ (((record.dailyAmount * record.days + record.monthAmount * record.month) * record.payRate / 100) - (record.dailyAmount * record.days * (record.taxRate / 100))).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'remark'">
|
||||
@@ -55,6 +70,30 @@
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<template #summary>
|
||||
<a-table-summary-row>
|
||||
<a-table-summary-cell>合计</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.tax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithoutTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
</a-table-summary-row>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
@@ -113,6 +152,16 @@ const columns = ref<ColumnItem[]>([
|
||||
dataIndex: "settleCycle",
|
||||
key: "settleCycle"
|
||||
},
|
||||
{
|
||||
title: "实际进场日期",
|
||||
dataIndex: "inDate",
|
||||
key: "inDate"
|
||||
},
|
||||
{
|
||||
title: "实际出场日期",
|
||||
dataIndex: "outDate",
|
||||
key: "outDate"
|
||||
},
|
||||
{
|
||||
title: "月工资(元)",
|
||||
dataIndex: "monthAmount",
|
||||
@@ -123,6 +172,11 @@ const columns = ref<ColumnItem[]>([
|
||||
dataIndex: "dailyAmount",
|
||||
key: "dailyAmount"
|
||||
},
|
||||
{
|
||||
title: "支付比例",
|
||||
dataIndex: "payRate",
|
||||
key: "payRate"
|
||||
},
|
||||
{
|
||||
title: "含税金额(元)",
|
||||
dataIndex: "amountWithTax",
|
||||
@@ -154,8 +208,9 @@ const dataList = ref<SettleDetail[]>([]);
|
||||
|
||||
const changeDate = (data, index) => {
|
||||
if (dataList.value[index].startDate && dataList.value[index].endDate) {
|
||||
dataList.value[index].days = dayjs(dataList.value[index].endDate).diff(dayjs(dataList.value[index].startDate), "day");
|
||||
console.log(dataList.value[index].days)
|
||||
dataList.value[index].days = dayjs(dataList.value[index].endDate).diff(dayjs(dataList.value[index].startDate), "day") + 1;
|
||||
dataList.value[index].month = Math.floor(dataList.value[index].days / 30);
|
||||
dataList.value[index].day = dataList.value[index].days - (Math.floor(dataList.value[index].days / 30) * 30);
|
||||
if (dataList.value[index].monthAmount) dataList.value[index].dailyAmount = (dataList.value[index].monthAmount / 30).toFixed(8);
|
||||
}
|
||||
};
|
||||
@@ -164,15 +219,39 @@ const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const totals = ref({ amountWithTax: 0, tax: 0, amountWithoutTax: 0 });
|
||||
const calTotals = () => {
|
||||
let amountWithTax = 0;
|
||||
let tax = 0;
|
||||
let amountWithoutTax = 0;
|
||||
if (dataList.value && dataList.value.length > 0 && (dataList.value[0].taxRate !== undefined)) {
|
||||
const taxRate = dataList.value[0].taxRate;
|
||||
dataList.value.forEach(({ month, monthAmount, day, dailyAmount, payRate }) => {
|
||||
amountWithTax += (month * monthAmount + day * dailyAmount) * payRate / 100;
|
||||
});
|
||||
amountWithTax = Number(amountWithTax.toFixed(2));
|
||||
tax = amountWithTax * (taxRate / 100);
|
||||
tax = Number(tax.toFixed(2));
|
||||
amountWithoutTax = amountWithTax - tax;
|
||||
amountWithoutTax = Number(amountWithoutTax.toFixed(2));
|
||||
}
|
||||
totals.value = { amountWithTax, tax, amountWithoutTax };
|
||||
};
|
||||
onMounted(() => {
|
||||
dataList.value = props.dataSource;
|
||||
calTotals();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
calTotals();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
|
||||
defineExpose({ dataList })
|
||||
defineExpose({ dataList });
|
||||
|
||||
</script>
|
||||
|
||||
@@ -10,6 +10,22 @@
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-if="column.key === 'inDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择实际进场日期"
|
||||
v-model:value="record.inDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'outDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择实际出场日期"
|
||||
v-model:value="record.outDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'singleAmount'">
|
||||
<a-input v-model:value="record.singleAmount" type="number" />
|
||||
</template>
|
||||
@@ -19,22 +35,24 @@
|
||||
<template v-if="column.key === 'unit'">
|
||||
<a-input v-model:value="record.unit" />
|
||||
</template>
|
||||
<template v-if="column.key === 'sumAmount'">
|
||||
<span v-if="record.singleAmount && record.num">
|
||||
{{ (record.singleAmount * record.num).toFixed(2) }}
|
||||
</span>
|
||||
<template v-if="column.key === 'payRate'">
|
||||
<a-input v-model:value="record.payRate" type="number">
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithTax'">
|
||||
<span v-if="record.singleAmount && record.num">{{ (record.singleAmount * record.num).toFixed(2) }}</span>
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ ((record.singleAmount * record.num) * record.payRate / 100).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'tax'">
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ (record.singleAmount * record.num * (record.taxRate / 100)).toFixed(2)
|
||||
v-if="record.singleAmount && record.num">{{ ((record.singleAmount * record.num) * record.payRate / 100 * (record.taxRate / 100)).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithoutTax'">
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ ((record.singleAmount * record.num) - (record.singleAmount * record.num * (record.taxRate / 100))).toFixed(2)
|
||||
v-if="record.singleAmount && record.num">{{ (((record.singleAmount * record.num) * record.payRate / 100) - (record.singleAmount * record.num * (record.taxRate / 100))).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'remark'">
|
||||
@@ -47,6 +65,29 @@
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<template #summary>
|
||||
<a-table-summary-row>
|
||||
<a-table-summary-cell>合计</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.tax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithoutTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
</a-table-summary-row>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
@@ -59,7 +100,7 @@ import {
|
||||
CloseCircleOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import dayjs from "dayjs";
|
||||
import { DictDataParam } from "@/api/system/dict-data/model";
|
||||
import { DictData, DictDataParam } from "@/api/system/dict-data/model";
|
||||
import { listDictData } from "@/api/system/dict-data";
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -67,7 +108,7 @@ const props = defineProps<{
|
||||
}>();
|
||||
const tableRef0 = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
const dictList = ref<DictDataParam[]>([]);
|
||||
const dictList = ref<DictData[]>([]);
|
||||
const getDictList = async () => {
|
||||
dictList.value = await listDictData({ dictId: 146 });
|
||||
};
|
||||
@@ -97,6 +138,16 @@ const columns = ref<ColumnItem[]>([
|
||||
dataIndex: "factoryNo",
|
||||
key: "factoryNo"
|
||||
},
|
||||
{
|
||||
title: "实际进场日期",
|
||||
dataIndex: "inDate",
|
||||
key: "inDate"
|
||||
},
|
||||
{
|
||||
title: "实际出场日期",
|
||||
dataIndex: "outDate",
|
||||
key: "outDate"
|
||||
},
|
||||
{
|
||||
title: "费用类型",
|
||||
dataIndex: "settleCostType",
|
||||
@@ -117,6 +168,11 @@ const columns = ref<ColumnItem[]>([
|
||||
dataIndex: "unit",
|
||||
key: "unit"
|
||||
},
|
||||
{
|
||||
title: "支付比例",
|
||||
dataIndex: "payRate",
|
||||
key: "payRate"
|
||||
},
|
||||
{
|
||||
title: "含税金额(元)",
|
||||
dataIndex: "amountWithTax",
|
||||
@@ -148,21 +204,42 @@ const dataList = ref<SettleDetail[]>([]);
|
||||
|
||||
const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
calTotals();
|
||||
};
|
||||
|
||||
const totals = ref({ amountWithTax: 0, tax: 0, amountWithoutTax: 0 });
|
||||
const calTotals = () => {
|
||||
let amountWithTax = 0;
|
||||
let tax = 0;
|
||||
let amountWithoutTax = 0;
|
||||
if (dataList.value && dataList.value.length > 0 && (dataList.value[0].taxRate !== undefined)) {
|
||||
const taxRate = dataList.value[0].taxRate;
|
||||
dataList.value.forEach(({ singleAmount, num, payRate }) => {
|
||||
amountWithTax += singleAmount * num * payRate / 100;
|
||||
});
|
||||
amountWithTax = Number(amountWithTax.toFixed(2));
|
||||
tax = amountWithTax * (taxRate / 100);
|
||||
tax = Number(tax.toFixed(2));
|
||||
amountWithoutTax = amountWithTax - tax;
|
||||
amountWithoutTax = Number(amountWithoutTax.toFixed(2));
|
||||
}
|
||||
totals.value = { amountWithTax, tax, amountWithoutTax };
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
console.log(dataList.value);
|
||||
calTotals();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
getDictList();
|
||||
dataList.value = props.dataSource;
|
||||
});
|
||||
|
||||
defineExpose({ dataList })
|
||||
defineExpose({ dataList });
|
||||
|
||||
</script>
|
||||
|
||||
@@ -10,6 +10,22 @@
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-if="column.key === 'inDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择实际进场日期"
|
||||
v-model:value="record.inDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'outDate'">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择实际出场日期"
|
||||
v-model:value="record.outDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'singleAmount'">
|
||||
<a-input v-model:value="record.singleAmount" type="number" />
|
||||
</template>
|
||||
@@ -19,22 +35,24 @@
|
||||
<template v-if="column.key === 'unit'">
|
||||
<a-input v-model:value="record.unit" />
|
||||
</template>
|
||||
<template v-if="column.key === 'sumAmount'">
|
||||
<span v-if="record.singleAmount && record.num">
|
||||
{{ (record.singleAmount * record.num).toFixed(2) }}
|
||||
</span>
|
||||
<template v-if="column.key === 'payRate'">
|
||||
<a-input v-model:value="record.payRate" type="number">
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithTax'">
|
||||
<span v-if="record.singleAmount && record.num">{{ (record.singleAmount * record.num).toFixed(2) }}</span>
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ ((record.singleAmount * record.num) * record.payRate / 100).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'tax'">
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ (record.singleAmount * record.num * (record.taxRate / 100)).toFixed(2)
|
||||
v-if="record.singleAmount && record.num">{{ ((record.singleAmount * record.num) * record.payRate / 100 * (record.taxRate / 100)).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'amountWithoutTax'">
|
||||
<span
|
||||
v-if="record.singleAmount && record.num">{{ ((record.singleAmount * record.num) - (record.singleAmount * record.num * (record.taxRate / 100))).toFixed(2)
|
||||
v-if="record.singleAmount && record.num">{{ (((record.singleAmount * record.num) * record.payRate / 100) - (record.singleAmount * record.num * (record.taxRate / 100))).toFixed(2)
|
||||
}}</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'remark'">
|
||||
@@ -47,6 +65,29 @@
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<template #summary>
|
||||
<a-table-summary-row>
|
||||
<a-table-summary-cell>合计</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.tax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell>
|
||||
{{ totals.amountWithoutTax }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell />
|
||||
<a-table-summary-cell />
|
||||
</a-table-summary-row>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
@@ -59,7 +100,7 @@ import {
|
||||
CloseCircleOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import dayjs from "dayjs";
|
||||
import { DictDataParam } from "@/api/system/dict-data/model";
|
||||
import { DictData, DictDataParam } from "@/api/system/dict-data/model";
|
||||
import { listDictData } from "@/api/system/dict-data";
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -67,7 +108,7 @@ const props = defineProps<{
|
||||
}>();
|
||||
const tableRef0 = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
const dictList = ref<DictDataParam[]>([]);
|
||||
const dictList = ref<DictData[]>([]);
|
||||
const getDictList = async () => {
|
||||
dictList.value = await listDictData({ dictId: 147 });
|
||||
};
|
||||
@@ -97,6 +138,16 @@ const columns = ref<ColumnItem[]>([
|
||||
dataIndex: "factoryNo",
|
||||
key: "factoryNo"
|
||||
},
|
||||
{
|
||||
title: "实际进场日期",
|
||||
dataIndex: "inDate",
|
||||
key: "inDate"
|
||||
},
|
||||
{
|
||||
title: "实际出场日期",
|
||||
dataIndex: "outDate",
|
||||
key: "outDate"
|
||||
},
|
||||
{
|
||||
title: "费用类型",
|
||||
dataIndex: "settleCostType",
|
||||
@@ -117,6 +168,11 @@ const columns = ref<ColumnItem[]>([
|
||||
dataIndex: "unit",
|
||||
key: "unit"
|
||||
},
|
||||
{
|
||||
title: "支付比例",
|
||||
dataIndex: "payRate",
|
||||
key: "payRate"
|
||||
},
|
||||
{
|
||||
title: "含税金额(元)",
|
||||
dataIndex: "amountWithTax",
|
||||
@@ -148,21 +204,42 @@ const dataList = ref<SettleDetail[]>([]);
|
||||
|
||||
const del = (index: number) => {
|
||||
dataList.value.splice(index, 1);
|
||||
calTotals();
|
||||
};
|
||||
|
||||
const totals = ref({ amountWithTax: 0, tax: 0, amountWithoutTax: 0 });
|
||||
const calTotals = () => {
|
||||
let amountWithTax = 0;
|
||||
let tax = 0;
|
||||
let amountWithoutTax = 0;
|
||||
if (dataList.value && dataList.value.length > 0 && (dataList.value[0].taxRate !== undefined)) {
|
||||
const taxRate = dataList.value[0].taxRate;
|
||||
dataList.value.forEach(({ singleAmount, num, payRate }) => {
|
||||
amountWithTax += singleAmount * num * payRate / 100;
|
||||
});
|
||||
amountWithTax = Number(amountWithTax.toFixed(2));
|
||||
tax = amountWithTax * (taxRate / 100);
|
||||
tax = Number(tax.toFixed(2));
|
||||
amountWithoutTax = amountWithTax - tax;
|
||||
amountWithoutTax = Number(amountWithoutTax.toFixed(2));
|
||||
}
|
||||
totals.value = { amountWithTax, tax, amountWithoutTax };
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(dataSource) => {
|
||||
dataList.value = dataSource;
|
||||
console.log(dataList.value);
|
||||
calTotals();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
getDictList();
|
||||
dataList.value = props.dataSource;
|
||||
});
|
||||
|
||||
defineExpose({ dataList })
|
||||
defineExpose({ dataList });
|
||||
|
||||
</script>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<a-form-item label="结算项目" v-bind="validateInfos.contractId">
|
||||
<TowerContractSelectModel
|
||||
:placeholder="`请选择结算项目`"
|
||||
v-model:value="contactNumber"
|
||||
v-model:value="projectName"
|
||||
@done="chooseContract"
|
||||
/>
|
||||
</a-form-item>
|
||||
@@ -44,167 +44,168 @@
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="本期开始日期" v-bind="validateInfos.startDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择开始日期"
|
||||
v-model:value="form.startDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="结算方式">
|
||||
<a-select placeholder="请先选择项目" style="width: 250px" size="small" :disabled="!form.contractId"
|
||||
v-model:value="form.settleMethod">
|
||||
<a-select-option v-for="(item, index) in ContractSettleMethod" :key="index" :value="index">
|
||||
{{ item }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-form-item label="本期开始日期" v-bind="validateInfos.dateRange">
|
||||
<a-range-picker v-model:value="dateRange" picker="month" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="本期开始日期" v-bind="validateInfos.startDate">-->
|
||||
<!-- <a-date-picker-->
|
||||
<!-- class="ele-fluid"-->
|
||||
<!-- placeholder="请选择开始日期"-->
|
||||
<!-- v-model:value="form.startDate"-->
|
||||
<!-- valueFormat="YYYY-MM-DD"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- <a-form-item label="结算方式">-->
|
||||
<!-- <a-select placeholder="请先选择项目" style="width: 250px" size="small" :disabled="!form.contractId"-->
|
||||
<!-- v-model:value="form.settleMethod">-->
|
||||
<!-- <a-select-option v-for="(item, index) in ContractSettleMethod" :key="index" :value="index">-->
|
||||
<!-- {{ item }}-->
|
||||
<!-- </a-select-option>-->
|
||||
<!-- </a-select>-->
|
||||
<!-- </a-form-item>-->
|
||||
</a-col>
|
||||
<a-col :md="8" :sm="24" :xs="24">
|
||||
<a-form-item label="本期结束日期" v-bind="validateInfos.endDate">
|
||||
<a-date-picker
|
||||
class="ele-fluid"
|
||||
placeholder="请选择开始日期"
|
||||
v-model:value="form.endDate"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
<div v-if="[0, 3].indexOf(form.settleMethod) > -1">
|
||||
<span>每月</span>
|
||||
<a-select placeholder="必选项" style="width: 250px" size="small"
|
||||
v-model:value="form.extendMonthDate">
|
||||
<a-select-option v-for="item in dateList" :key="item" :value="item">
|
||||
{{ item }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<span>号</span>
|
||||
<span class="ml-05">至下月</span>
|
||||
<span class="ml-05" v-if="form.extendMonthDate">{{ form.extendMonthDate - 1 }}号</span>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- <a-col :md="8" :sm="24" :xs="24">-->
|
||||
<!-- <a-form-item label="本期结束日期" v-bind="validateInfos.endDate">-->
|
||||
<!-- <a-date-picker-->
|
||||
<!-- class="ele-fluid"-->
|
||||
<!-- placeholder="请选择开始日期"-->
|
||||
<!-- v-model:value="form.endDate"-->
|
||||
<!-- valueFormat="YYYY-MM-DD"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- <div v-if="[0, 3].indexOf(form.settleMethod) > -1">-->
|
||||
<!-- <span>每月</span>-->
|
||||
<!-- <a-select placeholder="必选项" style="width: 250px" size="small"-->
|
||||
<!-- v-model:value="form.extendMonthDate">-->
|
||||
<!-- <a-select-option v-for="item in dateList" :key="item" :value="item">-->
|
||||
<!-- {{ item }}-->
|
||||
<!-- </a-select-option>-->
|
||||
<!-- </a-select>-->
|
||||
<!-- <span>号</span>-->
|
||||
<!-- <span class="ml-05">至下月</span>-->
|
||||
<!-- <span class="ml-05" v-if="form.extendMonthDate">{{ form.extendMonthDate - 1 }}号</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </a-col>-->
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-form>
|
||||
<a-card>
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane :key="0" tab="租金结算">
|
||||
<template #default>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(0)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(0)">一键加载结算设备
|
||||
</a-button>
|
||||
<a-button :disabled="!form.startDate || !form.startDate" type="primary"
|
||||
@click.native="onyKeyAsyncDate(0)">同步结算起止日期
|
||||
</a-button>
|
||||
</div>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[0]" @change="changeTaxRate($event, 0)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane :key="0" tab="租金结算">
|
||||
<template #default v-if="activeKey === 0">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(0)">
|
||||
新增
|
||||
</a-button>
|
||||
<!-- <a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"-->
|
||||
<!-- type="primary" @click.native="oneKetAddEquipment(0)">一键加载结算设备-->
|
||||
<!-- </a-button>-->
|
||||
<!-- <a-button :disabled="!form.startDate || !form.startDate" type="primary"-->
|
||||
<!-- @click.native="onyKeyAsyncDate(0)">同步结算起止日期-->
|
||||
<!-- </a-button>-->
|
||||
</div>
|
||||
<table0 :data-source="dataSource[0]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :key="1" tab="进退场费">
|
||||
<template #default>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(1)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(1)">一键加载结算设备
|
||||
</a-button>
|
||||
<a-button :disabled="!form.startDate || !form.startDate" type="primary"
|
||||
@click.native="onyKeyAsyncDate(1)">同步结算起止日期
|
||||
</a-button>
|
||||
</div>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[1]" @change="changeTaxRate($event, 1)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[0]" @change="changeTaxRate($event, 0)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</div>
|
||||
<table0 :data-source="dataSource[0]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :key="1" tab="进退场费">
|
||||
<template #default v-if="activeKey === 1">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(1)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(1)">一键加载结算设备
|
||||
</a-button>
|
||||
<a-button :disabled="!form.startDate || !form.startDate" type="primary"
|
||||
@click.native="onyKeyAsyncDate(1)">同步结算起止日期
|
||||
</a-button>
|
||||
</div>
|
||||
<table1 :data-source="dataSource[1]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :key="2" tab="操作人员工资结算">
|
||||
<template #default>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(2)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(2)">一键加载结算设备
|
||||
</a-button>
|
||||
<a-button :disabled="!form.startDate || !form.startDate" type="primary"
|
||||
@click.native="onyKeyAsyncDate(2)">同步结算起止日期
|
||||
</a-button>
|
||||
</div>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[2]" @change="changeTaxRate($event, 2)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[1]" @change="changeTaxRate($event, 1)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</div>
|
||||
<table1 :data-source="dataSource[1]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :key="2" tab="操作人员工资结算">
|
||||
<template #default>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(2)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(2)">一键加载结算设备
|
||||
</a-button>
|
||||
<!-- <a-button :disabled="!form.startDate || !form.startDate" type="primary"-->
|
||||
<!-- @click.native="onyKeyAsyncDate(2)">同步结算起止日期-->
|
||||
<!-- </a-button>-->
|
||||
</div>
|
||||
<table2 :data-source="dataSource[2]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :key="3" tab="其他费用清单">
|
||||
<template #default>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(3)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(3)">一键加载结算设备
|
||||
</a-button>
|
||||
<a-button :disabled="!form.startDate || !form.startDate" type="primary"
|
||||
@click.native="onyKeyAsyncDate(3)">同步结算起止日期
|
||||
</a-button>
|
||||
</div>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[3]" @change="changeTaxRate($event, 3)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[2]" @change="changeTaxRate($event, 2)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</div>
|
||||
<table2 :data-source="dataSource[2]" v-if="activeKey === 2" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :key="3" tab="其他费用清单">
|
||||
<template #default v-if="activeKey === 3">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(3)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(3)">一键加载结算设备
|
||||
</a-button>
|
||||
<!-- <a-button :disabled="!form.startDate || !form.startDate" type="primary"-->
|
||||
<!-- @click.native="onyKeyAsyncDate(3)">同步结算起止日期-->
|
||||
<!-- </a-button>-->
|
||||
</div>
|
||||
<table3 :data-source="dataSource[3]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :key="4" tab="扣除项">
|
||||
<template #default>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(4)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(4)">一键加载结算设备
|
||||
</a-button>
|
||||
<a-button :disabled="!form.startDate || !form.startDate" type="primary"
|
||||
@click.native="onyKeyAsyncDate(4)">同步结算起止日期
|
||||
</a-button>
|
||||
</div>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[4]" @change="changeTaxRate($event, 4)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[3]" @change="changeTaxRate($event, 3)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</div>
|
||||
<table3 :data-source="dataSource[3]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :key="4" tab="扣除项">
|
||||
<template #default v-if="activeKey === 4">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex-1">
|
||||
<a-button :disabled="!form.contractId || contractEquipmentList.length === 0" type="primary"
|
||||
@click.native="doShowSelectEquipment(4)">
|
||||
选择结算设备
|
||||
</a-button>
|
||||
<a-button class="mx-05" :disabled="!form.contractId || contractEquipmentList.length === 0"
|
||||
type="primary" @click.native="oneKetAddEquipment(4)">一键加载结算设备
|
||||
</a-button>
|
||||
<!-- <a-button :disabled="!form.startDate || !form.startDate" type="primary"-->
|
||||
<!-- @click.native="onyKeyAsyncDate(4)">同步结算起止日期-->
|
||||
<!-- </a-button>-->
|
||||
</div>
|
||||
<table4 :data-source="dataSource[4]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-card>
|
||||
<a-input style="width: 300px" v-model:value="taxRate[4]" @change="changeTaxRate($event, 4)">
|
||||
<template #prefix>税率</template>
|
||||
<template #addonAfter>%</template>
|
||||
</a-input>
|
||||
</div>
|
||||
<table4 :data-source="dataSource[4]" />
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</ele-modal>
|
||||
<ele-modal
|
||||
:width="'80%'"
|
||||
@@ -237,7 +238,7 @@ import { Form, message } from "ant-design-vue";
|
||||
import { assignObject, EleProTable } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { Contract, ContractSettleMethod } from "@/api/tower/contract/model";
|
||||
import dayjs from "dayjs";
|
||||
import dayjs, { Dayjs } from "dayjs";
|
||||
|
||||
import { Settle } from "@/api/tower/settle/model";
|
||||
import { addSettle, updateSettle } from "@/api/tower/settle";
|
||||
@@ -310,7 +311,6 @@ const getDataSource = async () => {
|
||||
res.forEach(item => {
|
||||
if ((item.type === 0 || item.type === 2)) {
|
||||
const days = dayjs(item.endDate).diff(dayjs(item.startDate), "day");
|
||||
item.dailyAmount = (item.monthAmount / 30).toFixed(2);
|
||||
item = { ...item, ...{ days } };
|
||||
}
|
||||
dataSource.value[item.type].push(item);
|
||||
@@ -339,32 +339,40 @@ const rules = reactive({
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
startDate: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择开始日期",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
endDate: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择结束日期",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
// startDate: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: "请选择开始日期",
|
||||
// trigger: "blur"
|
||||
// }
|
||||
// ],
|
||||
// endDate: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: "请选择结束日期",
|
||||
// trigger: "blur"
|
||||
// }
|
||||
// ],
|
||||
settleNo: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入结算单号",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
],
|
||||
dateRange: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择所属期间",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
|
||||
});
|
||||
|
||||
const contactNumber = ref<string | undefined>("");
|
||||
const projectName = ref<string | undefined>("");
|
||||
const chooseContract = (res: Contract) => {
|
||||
contactNumber.value = res.contactNumber;
|
||||
projectName.value = res.projectName;
|
||||
form.contractId = res.contractId;
|
||||
form.settleMethod = res.settleMethod;
|
||||
form.startDate = res.startDate;
|
||||
@@ -374,6 +382,8 @@ const chooseContract = (res: Contract) => {
|
||||
|
||||
const { resetFields, validate, validateInfos } = useForm(form, rules);
|
||||
|
||||
const dateRange = ref<[Dayjs, Dayjs] | [string, string]>()
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
validate()
|
||||
@@ -385,9 +395,12 @@ const save = () => {
|
||||
let totalAmount = 0;
|
||||
dataSource.value.forEach(data => {
|
||||
data.forEach(item => {
|
||||
if ((item.type === 0 || item.type === 2) && item.dailyAmount && item.days) totalAmount += item.dailyAmount * item.days;
|
||||
else if ((item.type === 1 || item.type === 3) && item.singleAmount && item.num) totalAmount += item.singleAmount * item.num;
|
||||
else if (item.type === 4 && item.singleAmount && item.num) totalAmount -= item.singleAmount * item.num;
|
||||
if ((item.type === 0 || item.type === 2) && item.dailyAmount && item.days)
|
||||
totalAmount += (item.dailyAmount * item.day) + (item.monthAmount * item.month);
|
||||
else if ((item.type === 1 || item.type === 3) && item.singleAmount && item.num)
|
||||
totalAmount += item.singleAmount * item.num;
|
||||
else if (item.type === 4 && item.singleAmount && item.num)
|
||||
totalAmount -= item.singleAmount * item.num;
|
||||
});
|
||||
});
|
||||
data.totalAmount = totalAmount;
|
||||
@@ -446,7 +459,7 @@ const addDataSource = (data: ContractSettleEquipment, index) => {
|
||||
// factoryNo: data.factoryNo,
|
||||
startDate: form.startDate ?? "",
|
||||
endDate: form.endDate ?? "",
|
||||
monthAmount: 0,
|
||||
monthAmount: data.rentAmount ?? 0,
|
||||
taxRate: taxRate.value[index],
|
||||
singleAmount: 0,
|
||||
num: 0,
|
||||
@@ -454,7 +467,10 @@ const addDataSource = (data: ContractSettleEquipment, index) => {
|
||||
remark: "",
|
||||
userId: loginUser.value.userId,
|
||||
days,
|
||||
dailyAmount: 0
|
||||
dailyAmount: 0,
|
||||
inDate: "",
|
||||
outDate: "",
|
||||
payRate: 100
|
||||
});
|
||||
};
|
||||
|
||||
@@ -480,13 +496,15 @@ watch(
|
||||
loading.value = false;
|
||||
assignObject(form, props.data);
|
||||
isUpdate.value = true;
|
||||
contactNumber.value = props.data.contactNumber;
|
||||
projectName.value = props.data.projectName;
|
||||
getDataSource();
|
||||
getContractEquipmentList();
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
}
|
||||
} else {
|
||||
contactNumber.value = "";
|
||||
projectName.value = "";
|
||||
dataSource.value = [[], [], [], [], []];
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
{{ timeAgo(record.createTime) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-if="column.key === 'date'">
|
||||
{{ dayjs(record.startDate).format('YYYY-MM') }} ~ {{ dayjs(record.endDate).format('YYYY-MM') }}
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a @click="openEdit(record)">修改</a>
|
||||
@@ -73,6 +76,7 @@
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { pageSettle, removeBatchSettle, removeSettle } from "@/api/tower/settle";
|
||||
import { Settle, SettleParam } from "@/api/tower/settle/model";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const userStore = useUserStore();
|
||||
// 当前用户信息
|
||||
@@ -122,11 +126,6 @@
|
||||
hideInSetting: true,
|
||||
customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)
|
||||
},
|
||||
{
|
||||
title: '结算状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
},
|
||||
{
|
||||
title: '项目名称',
|
||||
dataIndex: 'projectName'
|
||||
@@ -135,13 +134,17 @@
|
||||
title: '合同编号',
|
||||
dataIndex: 'contactNumber'
|
||||
},
|
||||
// {
|
||||
// title: '结算开始日期',
|
||||
// dataIndex: 'endDate'
|
||||
// },
|
||||
// {
|
||||
// title: '结算结束日期',
|
||||
// dataIndex: 'endDate'
|
||||
// },
|
||||
{
|
||||
title: '结算开始日期',
|
||||
dataIndex: 'endDate'
|
||||
},
|
||||
{
|
||||
title: '结算结束日期',
|
||||
dataIndex: 'endDate'
|
||||
title: '所属期间',
|
||||
key: 'date'
|
||||
},
|
||||
{
|
||||
title: '本次结算总额',
|
||||
|
||||
Reference in New Issue
Block a user