feat:农机租赁管理接口对接完成

This commit is contained in:
李想 2025-03-21 16:15:46 +08:00
parent cfde330ac0
commit 2ba4c5c318
9 changed files with 353 additions and 39 deletions

View File

@ -1,9 +1,11 @@
import * as redBlackApi from './redAndBlank';
import * as materialApi from './material';
import * as knowledgeApi from './knowledge';
import * as leaseSuperviseApi from './leaseSupervise';
export default {
...materialApi,
...redBlackApi,
...knowledgeApi,
...leaseSuperviseApi,
};

View File

@ -0,0 +1,16 @@
import request from '@/utils/axios';
/* 租赁列表 */
export function getLeaseSuperviseList(params) {
return request('/input/machineLease/page', {
params,
});
}
/* 新增租赁 */
export function addLeaseSupervise(data) {
return request('/input/machineLease/save', {
method: 'POST',
data,
});
}

View File

@ -40,3 +40,32 @@ export const CRUD_VIEW_OPTIONS = {
selection: false,
menu: false,
};
/**
* @Title: 生成avue校验规则
* @param {Object} set 校验配置对象
* @param {string} set.msg 校验失败提示
* @param {Array<string>} set.trigger 校验触发条件
* @param {Array} set.otherRules 其他校验规则
* @returns {Array} 校验规则数组
*/
export function customRules(set = {}) {
const obj = Object.assign(
{
msg: '必要参数,不能为空',
trigger: ['change', 'blur'],
otherRules: [],
},
set
);
const { msg, trigger, otherRules } = obj;
let rulesArr = [
{
required: true,
message: msg,
trigger,
},
...otherRules,
];
return rulesArr;
}

View File

@ -99,24 +99,24 @@ const inputSuppliesRoutes = [
// },
// ],
// },
{
path: '/sub-government-affairs-service/enterpriseDealerCheck',
name: 'enterpriseDealerCheck',
component: () => import('@/views/inputSuppliesManage/enterpriseDealerCheck/index.vue'),
meta: { title: '企业经销商抽检', icon: 'Document' },
},
// {
// path: '/sub-government-affairs-service/enterpriseDealerCheck',
// name: 'enterpriseDealerCheck',
// component: () => import('@/views/inputSuppliesManage/enterpriseDealerCheck/index.vue'),
// meta: { title: '企业经销商抽检', icon: 'Document' },
// },
// {
// path: '/sub-government-affairs-service/useSupervise',
// name: 'useSupervise',
// component: () => import('@/views/inputSuppliesManage/useSupervise/index.vue'),
// meta: { title: '使用监管', icon: 'Document' },
// },
// {
// path: '/sub-government-affairs-service/leaseSupervise',
// name: 'leaseSupervise',
// component: () => import('@/views/inputSuppliesManage/leaseSupervise/index.vue'),
// meta: { title: '农机租赁监管', icon: 'Document' },
// },
{
path: '/sub-government-affairs-service/leaseSupervise',
name: 'leaseSupervise',
component: () => import('@/views/inputSuppliesManage/leaseSupervise/index.vue'),
meta: { title: '农机租赁监管', icon: 'Document' },
},
{
path: '/sub-government-affairs-service/redBlackRank',
name: 'redBlackRank',

View File

@ -1,5 +1,5 @@
<template>
<section class="custom_attrs_upload_content_lx" :style="{ '--columns': props.fileNum }">
<section class="custom_attrs_upload_content_lx" :style="{ '--columns': props.fileNum, padding: props.type == 'view' ? '20px 0' : '0px' }">
<el-upload
v-if="props.type != 'view' && props.upBtn"
class="custom-form__uploader"
@ -39,7 +39,7 @@ const props = defineProps({
},
limit: {
type: Number,
default: 1,
default: 5,
},
fileNum: {
type: Number,

View File

@ -20,8 +20,8 @@
@row-save="handleRowSave"
@row-update="handleRowUpdate"
>
<template #emnu="{ row }">
<el-button>button</el-button>
<template #menu="{ row }">
<el-button type="primary">详情</el-button>
</template>
</avue-crud>
</CustomCard>
@ -51,12 +51,15 @@ const data = ref([]);
const option = reactive({
...CRUD_OPTIONS,
selection: false,
refreshBtn: false,
column: [
{
hide: true,
search: true,
label: '关键字',
prop: 'keywords',
addDisplay: false,
viewDisplay: false,
},
{
label: '任务编号',

View File

@ -1,19 +1,262 @@
<template>
<CustomCard>租赁监管</CustomCard>
<CustomCard>
<h2>农机租赁管理</h2>
<br />
<avue-crud
ref="crudRef"
v-model:search="searchCondition"
v-model:page="pageData"
:data="data"
:option="option"
:table-loading="_loading"
:before-close="handleDialogClose"
@search-change="
(form, done) => {
getData(1);
done();
}
"
@search-reset="() => getData(1)"
@current-change="getData"
@size-change="getData"
@row-save="handleRowSave"
>
<template #menu="{ row }">
<el-button type="primary" @click="handleView(row)">详情</el-button>
</template>
<template #certiUrl-form="{ type }">
<Attrs v-model:attrs="certiAttrs" :type="type" :file-num="2" />
</template>
<template #contractUrl-form="{ type }">
<Attrs v-model:attrs="contractAttrs" :type="type" :file-num="2" />
</template>
</avue-crud>
</CustomCard>
</template>
<script setup>
import { ref } from 'vue';
import { ref, reactive, onMounted, h } from 'vue';
import CustomCard from '@/components/CustomCard.vue';
import { CRUD_OPTIONS, customRules } from '@/config';
import Attrs from '../common/Attrs.vue';
import inputSuppliesApi from '@/apis/inputSuppliesApi';
import { ElMessage } from 'element-plus';
onMounted(getData);
/* --------------- data --------------- */
// #region
const crudRef = ref();
const _loading = ref(false);
const searchCondition = ref({
tenant: '',
});
const pageData = ref({
currentPage: 1,
pageSize: 10,
total: 0,
});
const data = ref([]);
const option = reactive({
...CRUD_OPTIONS,
selection: false,
refreshBtn: false,
dialogWidth: '50%',
column: [
{
hide: true,
search: true,
label: '关键字',
prop: 'tenant',
addDisplay: false,
viewDisplay: false,
},
{
label: '承租方',
prop: 'tenant',
rules: customRules({ msg: '请输入承租方姓名' }),
},
{
hide: true,
label: '出租方',
prop: 'lessor',
rules: customRules({ msg: '请输入出租方姓名' }),
},
{
label: '承租方联系方式',
prop: 'tenantPhone',
rules: customRules({ msg: '请输入承租方联系方式' }),
},
{
hide: true,
label: '出租方联系方式',
prop: 'lessorPhone',
rules: customRules({ msg: '请输入出租方联系方式' }),
},
{
label: '租赁设备',
prop: 'leaseEquipment',
rules: customRules({ msg: '请输入租赁设备' }),
},
{
label: '租赁数量',
prop: 'leaseNumber',
type: 'number',
min: 1,
step: 1,
stepStrictly: true,
suffix: '台',
viewDisplay: false,
rules: customRules({ msg: '请输入租赁数量' }),
render: ({ row }) => `${row.leaseNumber}`,
},
{
hide: true,
label: '租赁数量',
prop: 'leaseNumber1',
addDisplay: false,
// renderForm: ({ row }) => h('span', {}, `${row.leaseNumber}`),
},
{
hide: true,
label: '支付方式',
prop: 'payMethod',
rules: customRules({ msg: '请选择支付方式' }),
},
{
label: '租赁期限',
prop: 'term',
addDisplay: false,
},
{
hide: true,
label: '租金',
prop: 'rent',
type: 'number',
min: 1,
step: 0.01,
precision: 2,
stepStrictly: true,
suffix: '元/天/台',
rules: customRules({ msg: '请输入租赁价格' }),
},
{
label: '合同金额',
prop: 'allMoney',
addDisplay: false,
rules: customRules({ msg: '请输入合同金额' }),
},
{
hide: true,
label: '起止时间',
prop: 'startEndTime',
type: 'datetimerange',
format: 'YYYY-MM-DD HH:mm',
valueFormat: 'YYYY-MM-DD HH:mm',
startPlaceholder: '开始时间',
endPlaceholder: '终止时间',
span: 24,
rules: customRules({ msg: '请选择起止时间' }),
},
{
hide: true,
label: '机械合格证',
prop: 'certiUrl',
},
{
hide: true,
label: '租赁合同',
prop: 'contractUrl',
},
],
});
const certiAttrs = ref([]);
const contractAttrs = ref([]);
// #endregion
/* --------------- methods --------------- */
// #region
function handleDialogClose(done) {
certiAttrs.value = [];
contractAttrs.value = [];
done();
}
async function getData(resetPage) {
resetPage === 1 && (pageData.value.currentPage = 1);
_loading.value = true;
let params = Object.assign(
{
current: pageData.value.currentPage,
size: pageData.value.pageSize,
},
searchCondition.value
);
let res = await inputSuppliesApi.getLeaseSuperviseList(params);
_loading.value = false;
if (res.code == 200) {
data.value = res.data.records.map((v) => {
let d = leaseDate(v.startEndTime);
let obj = {
...v,
leaseNumber1: v.leaseNumber + '台',
term: d + '天',
allMoney: (v.rent * v.leaseNumber * d).toFixed(2) + '元',
};
return obj;
});
pageData.value.total = res.data.total;
}
}
async function handleRowSave(form, done, loading) {
let data = Object.assign({}, form);
delete data.allMoney;
if (certiAttrs.value.length) {
data.certiUrl = certiAttrs.value.map((v) => v.url).join();
}
if (contractAttrs.value.length) {
data.contractUrl = contractAttrs.value.map((v) => v.url).join();
}
data.startEndTime = data.startEndTime.join();
let res = await inputSuppliesApi.addLeaseSupervise(data);
loading();
if (res.code == 200) {
getData();
ElMessage.success('租赁信息添加成功');
// done();
}
}
function handleView(row) {
if (row.certiUrl) {
certiAttrs.value = row.certiUrl.split(',').map((v, i) => {
return {
url: v,
uid: `certi_${i}_${Date.now()}`,
};
});
}
if (row.contractUrl) {
contractAttrs.value = row.contractUrl.split(',').map((v, i) => {
return {
url: v,
uid: `contract_${i}_${Date.now()}`,
};
});
}
crudRef.value.rowView(row);
}
function leaseDate(date) {
let n = 0;
if (date) {
let arr = date.split(',');
let a1 = new Date(arr[0]).getTime();
let a2 = new Date(arr[1]).getTime();
n = Math.ceil((a2 - a1) / (1000 * 60 * 60 * 24));
}
return n;
}
// #endregion
</script>

View File

@ -38,6 +38,14 @@
</template>
</el-popconfirm>
</template>
<template #area-form="{ row, type }">
<section class="area_form_" style="">
<el-input-number v-model="landArea" :min="1" controls-position="right"></el-input-number>
<el-select v-model="unitValue">
<el-option v-for="item in unitOptions" :key="'unitOptions_' + item.value" :label="item.label" :value="item.value" />
</el-select>
</section>
</template>
<template #propertyCertificateUrl-form="{ type }">
<Attrs v-model:attrs="attrs" :type="type" />
</template>
@ -88,6 +96,13 @@ const params = ref({
const local_ = ref([102.833669, 24.88149, '昆明市']);
const local = ref(JSON.parse(JSON.stringify(local_.value)));
const landTreeDic = ref([]);
const landArea = ref(1);
const unitValue = ref('0');
const unitOptions = reactive([
{ label: '平方米', value: '0' },
{ label: '亩', value: '1' },
{ label: '公顷', value: '2' },
]);
/* --------------- data --------------- */
// #region
const loading = ref(false);
@ -150,6 +165,13 @@ const option = reactive({
addDisplay: false,
display: false,
editDisplay: false,
render: ({ row }) => {
let s = '';
if (row.area && row.landUnit) {
s = row.area + unitOptions.find((v) => v.value == row.landUnit).label;
}
return s;
},
},
{
label: '坐标',
@ -514,6 +536,8 @@ function handleCloseFrom(done) {
landOwnerAttrs.value = [];
attrs.value = [];
landAttrs.value = [];
landArea.value = 1;
unitValue.value = '0';
local.value = JSON.parse(JSON.stringify(local_.value));
done();
}
@ -533,6 +557,8 @@ async function handleRowSave(val, done, loading) {
if (landAttrs.value.length) {
landAttrs.value.forEach((item) => landUrls.push(item.url));
}
data.area = landArea.value;
data.landUnit = unitValue.value;
data.propertyCertificateUrl = urls.join();
data.landCertificateUrl = landOwnerUrls.join();
data.landUrl = landUrls.join();
@ -611,4 +637,20 @@ function newTree(arr, i) {
}
}
}
.area_form_ {
display: grid;
grid-template-columns: 75% 25%;
::v-deep() {
.el-input-number {
width: 100%;
.el-input__wrapper {
border-radius: 4px 0 0 4px;
}
}
.el-select__wrapper {
border-radius: 0 4px 4px 0 !important;
border-left: none;
}
}
}
</style>

View File

@ -15,29 +15,8 @@ export default function useLandHook() {
label: '园林',
},
]);
const landClassificationType = reactive([
{ label: '耕地', value: '0' },
{ label: '果园', value: '1' },
{ label: '茶园', value: '2' },
{ label: '其他园地', value: '3' },
{ label: '林地', value: '4' },
{ label: '草地', value: '5' },
{ label: '其他农用地', value: '6' },
{ label: '农村宅基地', value: '7' },
]);
function handleIficationType(t = 0) {
let arr = landClassificationType.filter((v) => v.value == t);
let txt = '--';
if (arr.length > 0) {
txt = arr[0].label;
}
return txt;
}
return {
landType,
landsType,
landClassificationType,
handleIficationType,
};
}