Просмотр исходного кода

4.0.98 增加资产处置相关内容

liuyanpeng 1 год назад
Родитель
Сommit
fbd5a8e7d0

+ 1 - 1
package.json

@@ -1,7 +1,7 @@
 {
   "name": "client-base-v4",
   "description": "Leanwo Prodog Client",
-  "version": "4.0.97",
+  "version": "4.0.98",
   "author": "yangzhijie1488 <yangzhijie1488@163.com>",
   "scripts": {
     "ins": "npm install --registry http://wuzhixin.vip:4873",

+ 279 - 0
src/assetsDisposal/AssetCommonTable.vue

@@ -0,0 +1,279 @@
+<template>
+  <div class="tablePaganations">
+    <!-- <a-config-provider :locale="locale"> -->
+    <a-table
+      id="commonTable" class="ant-table-striped" bordered size="small" height="1000px" :loading="isLoading"
+      :show-header="isShowHeader" :data-source="dataSource" :columns="columns" :row-key="(record) => record.id"
+      :scroll="{ y: yScroll }" :pagination="havePage ? pagination : false" :row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)
+      " :row-selection="isSelect
+        ? {
+          selectedRowKeys: state.selectedRowKeys,
+          onSelect: selectEvent,
+          onSelectAll: isCheckbox ? selectAllEvent : null,
+          type: isCheckbox ? 'checkbox' : 'radio',
+          getCheckboxProps: (record) => ({
+            disabled: isDisabled ? true : false,
+          })
+        }
+        : null
+      " @change="tableChange" @resize-column="handleResizeColumn"
+    >
+      <template v-for="(item, index) in renderArr" #[item]="scope" :key="index">
+        <slot :name="item" :scope="scope" v-bind="scope || {}" />
+      </template>
+    </a-table>
+    <!-- </a-config-provider> -->
+  </div>
+</template>
+
+<script setup>
+import {
+  useSlots,
+  ref,
+  reactive,
+  defineProps,
+  defineEmits,
+  defineExpose,
+  watch,
+  onMounted,
+} from 'vue';
+import { getTableScroll } from '../common/tableScroll.js';
+
+const props = defineProps({
+  // 表格数据
+  dataSource: {
+    type: Object,
+    required: true,
+  },
+  // 表头数据
+  columns: {
+    type: Object,
+    required: true,
+  },
+  // 是否可选择
+  isSelect: {
+    type: Boolean,
+  },
+  // 表格loading
+  isLoading: {
+    type: Boolean,
+  },
+  // 数据总数
+  total: {
+    type: Number,
+    default: 0,
+  },
+  // 是否分页
+  havePage: {
+    type: Boolean,
+    default: true,
+  },
+  // 表格距底部高度
+  extraHeight: {
+    type: Number,
+    default: undefined,
+  },
+  // 选择的key值
+  selectedKeys: {
+    type: Array,
+    default: () => [],
+  },
+  // 是否禁用选择
+  isDisabled: {
+    type: Boolean,
+    default: false,
+  },
+  // 是否多选
+  isCheckbox: {
+    type: Boolean,
+    default: true,
+  },
+  // 是否显示表头
+  isShowHeader: {
+    type: Boolean,
+    default: true,
+  },
+  // 是否在别的控件里
+  isInTable: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+const emit = defineEmits(['getPager', 'getSorter', 'getSelected']);
+
+// 分页配置
+const pagination = reactive({
+  showQuickJumper: true,
+  current: 1,
+  pageSize: 20, // 默认每页显示数量
+  showSizeChanger: true, // 显示可改变每页数量
+  pageSizeOptions: ['10', '20', '50', '100', '200', '500'], // 每页数量选项值
+  showTotal: (total, range) =>
+    range[0] + '-' + range[1] + '条' + ' 共' + total + '条', // 显示总数
+  onShowSizeChange: (current, pageSize) => showSizeChange(current, pageSize),
+  onChange: (current, pageSize) => changePage(current, pageSize), //点击页码事件
+  total: props.total,
+});
+
+const yScroll = ref(400); //默认滚动高度
+const extraHeight = ref(undefined); //表格距离底部值
+
+// 最后一次排序信息
+const lastSorter = reactive({ field: '', order: '' });
+
+//  选择的数据
+const state = reactive({
+  selectedRows: [],
+  selectedRowKeys: [],
+});
+
+onMounted(() => {
+  if (!props.havePage) {
+    extraHeight.value = 30;
+  } else {
+    extraHeight.value = props.extraHeight;
+  }
+  onResizeTable();
+  window.onresize = () => {
+    onResizeTable();
+  };
+});
+
+// 表格位置
+const onResizeTable = () => {
+  if (!props.isInTable) {
+    yScroll.value = getTableScroll({
+      extraHeight: extraHeight.value,
+      id: 'commonTable',
+    });
+  } else {
+    yScroll.value = props.extraHeight;
+  }
+};
+
+//点击页码事件
+const changePage = (current, size) => {
+  pagination.current = current;
+  emit('getPager', pagination.current, size);
+};
+
+// 改变每页数量时更新显示
+const showSizeChange = (current, pageSize) => {
+  setTimeout(() => {
+    pagination.current = 1;
+    emit('getPager', pagination.current, pageSize);
+  });
+  pagination.pageSize = pageSize;
+};
+
+// 回到第一页
+const backFirstPage = () => {
+  pagination.current = 1;
+  emit('getPager', pagination.current, pagination.pageSize);
+};
+
+// 伸缩列
+const handleResizeColumn = (w, col) => {
+  col.width = w;
+};
+
+// 选择每一项操作
+const selectEvent = (record, selected) => {
+  if (selected) {
+    if (props.isCheckbox) {
+      state.selectedRows.push(record);
+      state.selectedRowKeys.push(record.id);
+    } else {
+      state.selectedRows = [record];
+      state.selectedRowKeys = [record.id];
+    }
+  } else {
+    let index = state.selectedRowKeys.indexOf(record.id);
+    if (index >= 0) {
+      state.selectedRows.splice(index, 1);
+      state.selectedRowKeys.splice(index, 1);
+    }
+  }
+  emit('getSelected', state);
+};
+
+// 点击以后全选当前分页数据
+const selectAllEvent = (selected, selectedRows, changeRows) => {
+  if (selected) {
+    changeRows.forEach(item => {
+      state.selectedRows.push(item);
+      state.selectedRowKeys.push(item.id);
+    });
+  } else {
+    changeRows.forEach(item => {
+      let index = state.selectedRowKeys.indexOf(item.id);
+      if (index >= 0) {
+        state.selectedRows.splice(index, 1);
+        state.selectedRowKeys.splice(index, 1);
+      }
+    });
+  }
+  emit('getSelected', state);
+};
+
+// 清空选择
+const clear = () => {
+  state.selectedRowKeys = [];
+  state.selectedRows = [];
+  emit('getSelected', state);
+};
+
+// 获取排序信息
+const tableChange = (pagination, filters, sorter) => {
+  // pagination, filters 变化时也会触发所以对sorter进行判断限制执行
+  if (Object.keys(sorter).length > 0) {
+    if (sorter.field != lastSorter.field && sorter.order != lastSorter.order) {
+      lastSorter.field = sorter.field;
+      lastSorter.order = sorter.order;
+      emit('getSorter', sorter);
+    }
+    if (sorter.field != lastSorter.field && sorter.order == lastSorter.order) {
+      lastSorter.field = sorter.field;
+      lastSorter.order = sorter.order;
+      emit('getSorter', sorter);
+    }
+    if (sorter.field == lastSorter.field && sorter.order != lastSorter.order) {
+      lastSorter.field = sorter.field;
+      lastSorter.order = sorter.order;
+      emit('getSorter', sorter);
+    }
+  }
+};
+
+// 暴露出方法
+defineExpose({ backFirstPage, clear });
+
+// 监听total变化
+watch(
+  props,
+  newData => {
+    pagination.total = newData.total;
+    extraHeight.value = newData.extraHeight;
+    if(!newData.isCheckbox){
+      state.selectedRowKeys = [...newData.selectedKeys];
+    } else{
+      state.selectedRowKeys = newData.selectedKeys;
+    }
+  },
+  { immediate: true, deep: true },
+);
+// 插槽的实例
+const slots = useSlots();
+const renderArr = Object.keys(slots);
+</script>
+<style scoped>
+.tablePaganations {
+  width: 100%;
+  margin-top: 8px;
+}
+
+.ant-table-striped :deep(.table-striped) td {
+  background-color: #fafafa;
+}
+</style>

+ 254 - 0
src/assetsDisposal/AssetsDisposal.vue

@@ -0,0 +1,254 @@
+<template>
+  <Navbar title="资产处置-处置申请单" :is-go-back="true" />
+  <a-row style="display: flex;justify-content: space-between;align-items: center;">
+    <a-col :span="10">
+      <a-steps :current="current" size="small" type="navigation" :style="stepStyle" :items="steps" />
+    </a-col>
+    <a-col>
+      <a-button v-if="current > 0" style="margin-right: 8px" @click="prev">上一步</a-button>
+      <a-button v-if="current < steps.length - 1" type="primary" @click="next">下一步</a-button>
+      <a-button v-if="current == steps.length - 1 && !isReadonly" type="primary" @click="saveForm">
+        确定
+      </a-button>
+    </a-col>
+  </a-row>
+  <span v-if="current !== 2 && !isReadonly" style="color: red;">注意:处置方式为 “无偿调拨” 和 “捐赠” 的情况不需要选择中介机构,您可以直接单击 "下一步"
+    。</span>
+  <keep-alive>
+    <DisposalStep1
+      v-if="current === 0" :disposal-id="disposalId" :is-readonly="isReadonly"
+      @get-disposal-way="getDisposalWay" @get-nature-ids="getNatureIds"
+    />
+  </keep-alive>
+  <keep-alive>
+    <DisposalStep2 v-if="current === 1" ref="disposal2" :disposal-id="disposalId" :is-readonly="isReadonly" />
+  </keep-alive>
+  <keep-alive>
+    <DisposalStep3
+      v-if="current === 2" ref="disposal3" :disposal-id="disposalId" :disposal-way="disposalWay"
+      :is-readonly="isReadonly"
+    />
+  </keep-alive>
+</template>
+
+<script setup>
+import { onMounted, ref } from 'vue';
+import Common from '../common/Common';
+import { Uuid } from 'pc-component-v3';
+import { message } from 'ant-design-vue';
+import DisposalStep1 from './DisposalStep1.vue';
+import DisposalStep2 from './DisposalStep2.vue';
+import DisposalStep3 from './DisposalStep3.vue';
+import { addAgencyApi, saveDisposalTwoApi, saveThreeApi, queryStatusApi, saveMaterialApi } from './api.js';
+
+const current = ref(0);
+
+const natureIds = ref(null);
+
+const disposalId = ref('');
+
+const disposalWay = ref('');
+
+const disposal2 = ref();
+const disposal3 = ref();
+
+const isReadonly = ref(false);
+
+const steps = [
+  {
+    title: '选择中介机构',
+  },
+  {
+    title: '中介机构出具报告',
+  },
+  {
+    title: '填写表单信息',
+  },
+];
+
+
+onMounted(() => {
+  disposalId.value = getQueryParams().disposalId;
+  if (disposalId.value) queryStatus();
+});
+
+// 获取处置方式
+const getDisposalWay = way => {
+  disposalWay.value = way;
+};
+
+// 获取中介机构ids
+const getNatureIds = id => {
+  natureIds.value = id;
+};
+
+
+const next = () => {
+  if (isReadonly.value) {
+    current.value++;
+    return;
+  }
+  if (current.value === 0) {
+    if (disposalWay.value === '无偿调拨' || disposalWay.value === '捐赠') {
+      current.value++;
+      return;
+    }
+    if (natureIds.value) {
+      addAgency();
+    } else {
+      current.value++;
+    }
+  } else if (current.value === 1) {
+    saveDisposalTwo();
+  }
+};
+const prev = () => {
+  current.value--;
+};
+
+// 查询处置的状态
+const queryStatus = () => {
+  queryStatusApi(disposalId.value).then(
+    success => {
+      if (success.errorCode === 0) {
+        if (success.data.value === '待审核') {
+          isReadonly.value = false;
+        } else {
+          isReadonly.value = true;
+          current.value = 2;
+        }
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+// 保存表单数据
+const saveForm = () => {
+  const formDatas = { ...disposal3.value.formState };
+  const { operatorName, operatorNum, documentNumber, applyFileName, responsibilityName, disposalReason } = formDatas;
+  if (!operatorName) {
+    message.warning('请您填写经办人。');
+    return;
+  }
+  if (!operatorNum) {
+    message.warning('请您填写经办人联系方式。');
+    return;
+  }
+  if (!documentNumber) {
+    message.warning('请您填写文号。');
+    return;
+  }
+  if (!applyFileName) {
+    message.warning('请您填写单位申请文件名称。');
+    return;
+  }
+  if (!responsibilityName) {
+    message.warning('请您填写责任人名称。');
+    return;
+  }
+  const params = {
+    assetDisposalApplyId: disposalId.value,
+    operatorName,
+    operatorNum,
+    documentNumber,
+    applyFileName,
+    responsibilityName,
+    disposalReason,
+  };
+  saveThreeApi(params).then(
+    success => {
+      if (success.errorCode === 0) {
+        message.success('生成资产处置单成功。');
+        saveFile();
+
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+const saveFile = () => {
+  const params = {
+    assetDisposalApplyId: disposalId.value,
+    attachmentMaterialsIds: disposal3.value.fileIds,
+  };
+  saveMaterialApi(params).then(
+    success => {
+      if (success.errorCode === 0) {
+        window.open(
+          '/#/desktop/window1/20241101_113732' + '?uuid=' + Uuid.createUUID(),
+          '_self',
+        );
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+// 添加中介
+const addAgency = () => {
+  const params = {
+    assetDisposalApplyId: disposalId.value,
+    assetAgencyId: natureIds.value,
+  };
+  addAgencyApi(params).then(
+    success => {
+      if (success.errorCode !== 0) {
+        message.warning(success.errorMessage);
+      } else {
+        current.value++;
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+// 保存中介机构出具报告
+const saveDisposalTwo = () => {
+  const params = {
+    ...disposal2.value.getSaveDatas(),
+  };
+  saveDisposalTwoApi(params).then(
+    success => {
+      if (success.errorCode !== 0) {
+        message.warning(success.errorMessage);
+      } else {
+        current.value++;
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+// 获取单据Id
+const getQueryParams = () => {
+  const url = window.location.href;
+  let urlStr = url.split('?')[1];
+  const urlSearchParams = new URLSearchParams(urlStr);
+  const result = Object.fromEntries(urlSearchParams.entries());
+  return result;
+};
+const stepStyle = {
+  marginBottom: '8px',
+  boxShadow: '0px -1px 0 0 #e8e8e8 inset',
+};
+</script>
+
+<style scoped></style>

+ 127 - 0
src/assetsDisposal/DisposalStep1.vue

@@ -0,0 +1,127 @@
+<template>
+  <div>
+    <CommonTable ref="typeTable" :have-page="false" :columns="typeColumns" :data-source="typeDatas">
+      <template #title>资产类型</template>
+      <template #bodyCell="{ column }">
+        <template v-if="column.dataIndex === 'operation'">
+          <a-button type="link">查看明细</a-button>
+        </template>
+      </template>
+    </CommonTable>
+    <CommonTable
+      ref="organizationTable" :have-page="false" :is-in-table="true" :extra-height="460" :is-select="true"
+      :is-checkbox="false" :selected-keys="selectedKeys" :is-disabled="isReadonly" :columns="natureColumns"
+      :data-source="natureDatas" @get-selected="getSelectColumn"
+    >
+      <template #title>
+        <a-flex justify="space-between" align="center">
+          <div>
+            <label for="">请您选择中介机构性质:</label>
+            <a-select
+              v-model:value="nature" size="small" :disabled="isReadonly" :options="natures"
+              style="width: 150px;"
+            />
+          </div>
+          <a-input-search
+            v-model:value="searchValue" style="width: 200px;" size="small" placeholder="请输入查询"
+            enter-button @search="searchDatas"
+          />
+        </a-flex>
+      </template>
+    </CommonTable>
+  </div>
+</template>
+
+<script setup>
+import { message } from 'ant-design-vue';
+import Common from '../common/Common.js';
+import CommonTable from './AssetCommonTable.vue';
+import { queryById, queryNaturesApi } from './api.js';
+import { ref, defineProps, defineEmits, watch } from 'vue';
+import { typeColumn, natureColumn } from './assetConfig.js';
+
+const emits = defineEmits(['getDisposalWay', 'getNatureIds']);
+const props = defineProps({
+  disposalId: {
+    type: String,
+    default: null,
+  },
+  isReadonly: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+const typeTable = ref();
+const typeDatas = ref([]);
+
+const nature = ref('资产评估机构');
+const natures = ref([{
+  label: '资产评估机构',
+  value: '资产评估机构',
+}]);
+const natureDatas = ref([]);
+
+const typeColumns = ref(typeColumn);
+const natureColumns = ref(natureColumn);
+
+const searchValue = ref('');
+const selectedKeys = ref([]);
+
+watch(() => props.disposalId, newValue => {
+  if (newValue) {
+    queryAsset();
+    queryNatures('');
+  }
+});
+
+// 获取所选项的数据
+const getSelectColumn = selected => {
+  selectedKeys.value=selected.selectedRowKeys;
+  emits('getNatureIds', selected.selectedRowKeys[0]);
+};
+
+// 搜索中介
+const searchDatas = str => {
+  queryNatures(str);
+};
+
+// 查询资产类型
+const queryAsset = () => {
+  queryById(props.disposalId).then(
+    success => {
+      if (success.errorCode === 0) {
+        typeDatas.value = [success.data];
+        emits('getDisposalWay', success.data.disposalWay);
+        selectedKeys.value = [success.data.assetAgencyId];
+        emits('getNatureIds', selectedKeys.value[0]);
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+// 查询中介机构
+const queryNatures = str => {
+  queryNaturesApi(str).then(
+    success => {
+      if (success.errorCode === 0) {
+        if (success.datas) {
+          natureDatas.value = success.datas;
+        }
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+</script>
+
+<style scoped></style>

+ 246 - 0
src/assetsDisposal/DisposalStep2.vue

@@ -0,0 +1,246 @@
+<template>
+  <div>
+    <CommonTable :have-page="false" :columns="orgColumns" :data-source="orgDatas">
+      <template #title><span>中介机构</span></template>
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.dataIndex === 'evaluationNumber'">
+          <a-input v-model:value="record.evaluationNumber" :disabled="isReadonly" style="width:100%;" />
+        </template>
+        <template v-if="column.dataIndex === 'intermediaryFees'">
+          <a-input-number
+            v-model:value="record.intermediaryFees" :disabled="isReadonly" :controls="false" :step="0.01"
+            style="width: 100%;"
+          />
+        </template>
+        <template v-if="column.dataIndex === 'operation'">
+          <a-button type="link">评价</a-button>
+        </template>
+      </template>
+    </CommonTable>
+    <CommonTable
+      :have-page="false" :is-select="true" :columns="assetColumns" :data-source="assetDatas"
+      @get-selected="getSelectColumn"
+    >
+      <template #title>
+        <div><span>资产详情</span></div>
+        <a-divider style="margin: 8px 0;" />
+        <a-flex justify="space-between" align="center">
+          <a-space>
+            <a-button v-if="!isReadonly" size="small" :icon="h(PlusCircleTwoTone)" @click="openAdd = true">添加</a-button>
+            <a-button v-if="!isReadonly" size="small" :icon="h(DeleteTwoTone)" @click="deleteAssets">删除</a-button>
+            <a-input-search
+              v-model:value="searchValue" style="width: 200px;" size="small" placeholder="请输入查询"
+              enter-button @search="searchDatas"
+            />
+          </a-space>
+          <a-space>
+            <!-- <a-button>打印</a-button> -->
+            <a-pagination
+              v-model:current="pagination.current" v-model:pageSize="pagination.pageSize" size="small"
+              show-size-changer show-quick-jumper :total="assetTotal" @show-size-change="onShowSizeChange"
+            />
+          </a-space>
+        </a-flex>
+      </template>
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.dataIndex === 'evaluateValue'">
+          <a-input-number
+            v-model:value="record.evaluateValue" :disabled="isReadonly" :controls="false" :step="0.01" style="width: 100%;"
+            @blur="calculation"
+          />
+        </template>
+      </template>
+    </CommonTable>
+  </div>
+  <a-modal v-model:open="openAdd" title="添加资产详情" width="75%" :footer="null" @cancel="openAdd = false">
+    <InfoWindow
+      v-if="openAdd" :info-window-no="infoWindowNo" :multiple="true" :is-search-widget="true"
+      :is-new-similar-assets="true" :where-clause-source="whereClauseSource"
+      @get-select-model-data="getSelectModelData"
+    />
+  </a-modal>
+</template>
+
+<script setup>
+import Common from '../common/Common.js';
+import { message, Modal } from 'ant-design-vue';
+import CommonTable from './AssetCommonTable.vue';
+import { orgColumn, assetColumn } from './assetConfig.js';
+import { queryDetailApi, addApplyApi, reduceApplyApi } from './api.js';
+import { ref, reactive, defineProps, defineExpose, watch, h } from 'vue';
+import { PlusCircleTwoTone, DeleteTwoTone } from '@ant-design/icons-vue';
+
+
+const props = defineProps({
+  disposalId: {
+    type: String,
+    default: null,
+  },
+  isReadonly: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+const whereClauseSource = {
+  customWhere: 'ad.assetDisposalStatus = \'UNDER_REVIEW_CLIENT\' OR (ad.assetDisposalStatus = \'TO_BE_SUMMIT\' AND ad.roleTemplateWay = \'CLIENT\')',
+};
+
+const openAdd = ref(false);
+const infoWindowNo = ref('20241103_160417');
+
+const orgDatas = ref([]);
+const assetDatas = ref([]);
+
+const assetTotal = ref(0);
+const orgColumns = ref(orgColumn);
+const assetColumns = ref(assetColumn);
+const searchValue = ref('');
+
+const selectAssetIds = ref([]);
+
+const pagination = reactive({
+  current: 1,
+  pageSize: 20,
+});
+
+// 获取保存assetDisposalDto2s参数值
+const getSaveDatas = () => {
+  const dtos = assetDatas.value.map(item => {
+    return { id: item.assetDisposalId, evaluateValue: item.evaluateValue };
+  });
+  const datas = {
+    assetDisposalApplyId: props.disposalId,
+    evaluationNumber: orgDatas.value[0].evaluationNumber,
+    intermediaryFees: orgDatas.value[0].intermediaryFees,
+    assetDisposalDto2s: dtos,
+  };
+  return datas;
+};
+
+// 搜索资产详情
+const searchDatas = str => {
+  queryDetail(str);
+};
+
+const onShowSizeChange = (current, pageSize) => {
+  pagination.current = 1;
+};
+
+// 获取所选项的数据
+const getSelectColumn = selected => {
+  console.log(selected, '所选数据');
+  selectAssetIds.value = selected.selectedRowKeys;
+};
+
+// 获取添加的资产详情
+const getSelectModelData = selectedData => {
+  const modelDataIds = selectedData.map(item => {
+    return item.id;
+  });
+  addApply(modelDataIds);
+};
+
+// 计算评估总和
+const calculation = () => {
+  const arr1 = JSON.parse(JSON.stringify(assetDatas.value));
+  const arr2 = JSON.parse(JSON.stringify(orgDatas.value));
+  const total = arr1.reduce((acc, obj) => acc + obj.evaluateValue, 0);
+
+  arr2[0].evaluateValue = total.toFixed(2);
+  orgDatas.value = arr2;
+};
+
+// 删除资产详情
+const deleteAssets = () => {
+  if (selectAssetIds.value.length === 0) {
+    message.warning('请您先选择需要删除的资产。');
+    return;
+  }
+  Modal.confirm({
+    title: '提示',
+    content: h(
+      'div', {},
+      '您确定要删除吗?',
+    ),
+    onOk() {
+      const params = {
+        assetDisposalIds: selectAssetIds.value,
+        assetDisposalApplyId: props.disposalId,
+      };
+      reduceApplyApi(params).then(
+        success => {
+          if (success.errorCode === 0) {
+            message.success('删除成功');
+            queryDetail('');
+          } else {
+            message.warning(success.errorMessage);
+          }
+        },
+        error => {
+          Common.processException(error);
+        },
+      );
+    },
+  });
+
+};
+
+// 保存中介机构出具报告
+const addApply = ids => {
+  const params = {
+    assetDisposalIds: ids,
+    assetDisposalApplyId: props.disposalId,
+  };
+  addApplyApi(params).then(
+    success => {
+      if (success.errorCode === 0) {
+        message.success('添加成功');
+        openAdd.value = false;
+        queryDetail('');
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+// 根据资产处置申请单查询资产明细
+const queryDetail = str => {
+  queryDetailApi(props.disposalId, str).then(
+    success => {
+      if (success.errorCode === 0) {
+        const { assetInstanceDisposalDtos: dtos } = success.data;
+        dtos.forEach(item => {
+          item.id = item.assetDisposalId;
+        });
+        orgDatas.value = [{ ...success.data }];
+        assetDatas.value = dtos;
+        assetTotal.value = dtos.length;
+
+        calculation();
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+watch(() => props.disposalId, newValue => {
+  if (newValue) {
+    queryDetail('');
+  }
+}, { immediate: true });
+
+defineExpose({
+  getSaveDatas,
+});
+</script>
+
+<style scoped></style>

+ 141 - 0
src/assetsDisposal/DisposalStep3.vue

@@ -0,0 +1,141 @@
+<template>
+  <a-card size="small" title="填写表单信息">
+    <a-form
+      ref="formRef" :model="formState" :label-col="{
+        style: {
+          width: '150px',
+        },
+      }"
+    >
+      <a-row :gutter="24">
+        <template v-for="form in formDatas" :key="form.label">
+          <a-col v-if="!form.isLine" :span="8">
+            <a-form-item :name="form.key" :label="form.label" :rules="[{ required: form.isRequired }]">
+              <span v-if="form.type === 'span'" style="width: 210px;">{{ formState[form.key] }}</span>
+              <a-input
+                v-if="form.type === 'input' && form.key !== 'organizationCode'"
+                v-model:value="formState[form.key]" style="width: 210px;" size="small" :disabled="isReadonly"
+              />
+              <a-input
+                v-if="form.key === 'organizationCode'" v-model:value="formState[form.key]" style="width: 210px;"
+                size="small" :disabled="true"
+              />
+              <a-select
+                v-if="form.label === '接收方性质'" v-model:value="formState[form.key]" size="small"
+                :options="natures" style="width: 210px;" :disabled="true"
+              />
+              <a-select
+                v-if="form.label === '是否公车改革'" v-model:value="formState[form.key]" size="small"
+                :options="reforms" style="width: 210px;" :disabled="isReadonly"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col v-else :span="24">
+            <a-form-item :name="form.key" :label="form.label" :rules="[{ required: form.isRequired }]">
+              <a-input
+                v-if="form.type === 'input'" v-model:value="formState[form.key]" style="width: 100%;"
+                size="small" :disabled="true"
+              />
+              <a-textarea
+                v-if="form.type === 'textArea'" v-model:value="formState[form.key]" style="width: 100%;"
+                size="small" :disabled="isReadonly"
+              />
+            </a-form-item>
+          </a-col>
+        </template>
+      </a-row>
+    </a-form>
+  </a-card>
+  <AssetInformation :disposal-id="disposalId" :is-readonly="isReadonly" @get-file-ids="getFileIds" />
+</template>
+
+<script setup>
+import { queryThree } from './api.js';
+import { message } from 'ant-design-vue';
+import Common from '../common/Common.js';
+import { formConfig } from './assetConfig.js';
+import AssetInformation from './DisposalSummary.vue';
+import { watch, ref, defineProps, defineExpose, onMounted } from 'vue';
+
+const props = defineProps({
+  disposalId: {
+    type: String,
+    default: null,
+  },
+  disposalWay: {
+    type: String,
+    default: null,
+  },
+  isReadonly: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+const formRef = ref();
+const formState = ref({ reform: '否' });
+const formDatas = ref(formConfig);
+
+const fileIds = ref([]);
+
+const natures = ref([]);
+const reforms = ref([{ label: '是', value: '是' }, { label: '否', value: '否' }]);
+
+onMounted(() => {
+  formState.value.disposalWay = props.disposalWay;
+});
+
+const getFileIds = ids => {
+  fileIds.value = ids;
+};
+
+// 查询资产统计表数据
+const queryFormDetail = () => {
+  queryThree(props.disposalId).then(
+    success => {
+      if (success.errorCode === 0) {
+        formState.value = success.data;
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+watch(() => props.disposalId, newValue => {
+  if (newValue) {
+    queryFormDetail();
+  }
+}, { immediate: true });
+
+defineExpose({
+  formState,
+  fileIds,
+});
+</script>
+
+<style scoped>
+:deep(.ant-card-body) {
+  width: 70%;
+}
+
+/* :deep(.ant-card-small >.ant-card-body){
+    padding: 6px 10px !important;
+} */
+
+:deep(.ant-form-item) {
+  margin-bottom: 0 !important;
+}
+
+:deep(.ant-tabs >.ant-tabs-nav) {
+  margin-bottom: 4px !important;
+}
+
+:deep(.ant-form-item-label > label){
+  font-size: 14px !important;
+  font-weight: 500 !important;
+}
+</style>

+ 146 - 0
src/assetsDisposal/DisposalSummary.vue

@@ -0,0 +1,146 @@
+<template>
+  <a-card size="small" style="margin-top: 4px;">
+    <a-tabs v-model:activeKey="activeKey">
+      <a-tab-pane key="1" tab="处置资产统计表">
+        <CommonTable :have-page="false" :columns="statisticsColumns" :data-source="statisticsDatas" />
+      </a-tab-pane>
+      <a-tab-pane key="2" tab="附报材料" force-render>
+        <CommonTable
+          :is-show-header="false" :is-select="true" :have-page="false" :is-disabled="isReadonly"
+          :columns="materialsColumns" :data-source="materialsDatas" :selected-keys="fileIds"
+          @get-selected="getFileSelected"
+        />
+      </a-tab-pane>
+      <a-tab-pane key="3" tab="处置汇总表">
+        <CommonTable :have-page="false" :columns="summaryColumns" :data-source="summaryDatas" />
+      </a-tab-pane>
+      <template #rightExtra>
+        <a-button type="link">查看资产明细</a-button>
+      </template>
+    </a-tabs>
+  </a-card>
+</template>
+
+<script setup>
+import Common from '../common/Common.js';
+import { message } from 'ant-design-vue';
+import { SqlApi } from 'pc-component-v3';
+import CommonTable from './AssetCommonTable.vue';
+import { ref, defineProps, defineEmits, watch } from 'vue';
+import { queryTableApi, querySummaryApi, queryAttachmentApi } from './api.js';
+import { statisticsColumn, materialsColumn, summaryColumn } from './assetConfig.js';
+
+const emits = defineEmits(['getFileIds']);
+const props = defineProps({
+  disposalId: {
+    type: String,
+    default: null,
+  },
+  isReadonly: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+const activeKey = ref('1');
+const summaryColumns = ref(summaryColumn);
+const materialsColumns = ref(materialsColumn);
+const statisticsColumns = ref(statisticsColumn);
+
+const statisticsDatas = ref([]);
+const summaryDatas = ref([]);
+const materialsDatas = ref([]);
+
+const fileIds = ref([]);
+
+// 获取所选附件
+const getFileSelected = state => {
+  emits('getFileIds', state.selectedRowKeys);
+};
+
+// 查询资产统计表数据
+const queryTableDatas = () => {
+  queryTableApi(props.disposalId).then(
+    success => {
+      if (success.errorCode === 0) {
+        if (success.datas) statisticsDatas.value = success.datas;
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+// 根据处置申请单id查询其有的附报文件信息
+const queryAttachment = () => {
+  queryAttachmentApi(props.disposalId).then(
+    success => {
+      if (success.errorCode === 0) {
+        if (success.data) {
+          if (success.data.attachmentMaterialsIds && success.data.attachmentMaterialsIds.length) {
+            fileIds.value = success.data.attachmentMaterialsIds;
+            emits('getFileIds', success.data.attachmentMaterialsIds);
+          }
+        }
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+// 查询附件信息
+const queryFile = () => {
+  SqlApi.execute('20241104_182641').then(
+    successData => {
+      if (successData.errorCode == 0) {
+        materialsDatas.value = successData.results;
+        queryAttachment();
+      } else {
+        message.warning(successData.errorMessage);
+      }
+    },
+    errorData => {
+      Common.processException(errorData);
+    },
+  );
+};
+
+// 查询资产统计表数据
+const querySummary = () => {
+  querySummaryApi(props.disposalId).then(
+    success => {
+      if (success.errorCode === 0) {
+        if (success.datas) summaryDatas.value = success.datas;
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+watch(() => props.disposalId, newValue => {
+  if (newValue) {
+    queryFile();
+    querySummary();
+    queryTableDatas();
+  }
+}, { immediate: true });
+
+
+</script>
+
+<style scoped>
+:deep(.ant-card-body) {
+  padding-top: 0 !important;
+  width: 100% !important;
+}
+</style>

+ 330 - 0
src/assetsDisposal/api.js

@@ -0,0 +1,330 @@
+import Common from '../common/Common';
+
+// 根据id查询资产处置申请单
+export const queryById = id => {
+  const requestUrl = `assetDisposalApplyResource/queryByAssetDisposalApplyId?assetDisposalApplyId=${id}`;
+
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 查询中介信息
+export const queryNaturesApi = str => {
+  const requestUrl = `assetAgencyResource/queryAll?str=${str}`;
+
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 添加中介
+export const addAgencyApi = params => {
+  const requestUrl = 'assetDisposalApplyResource/addAssetAgency';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+
+      contentType: 'application/json',
+
+
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 根据资产处置申请单查询资产明细
+export const queryDetailApi = (id, str) => {
+  const requestUrl = `assetDisposalApplyResource/queryAssetDisposalDetail?assetDisposalApplyId=${id}&str=${str}`;
+
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 保存中介机构出具报告
+export const saveDisposalTwoApi = params => {
+  const requestUrl = 'assetDisposalApplyResource/saveAssetDisposalTwo';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+  
+      contentType: 'application/json',
+  
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 往申请单中添加资产
+export const addApplyApi = params => {
+  const requestUrl = 'assetDisposalApplyResource/addAssetDisposalInApply';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+  
+      contentType: 'application/json',
+  
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 删除申请单中所选资产
+export const reduceApplyApi = params => {
+  const requestUrl = 'assetDisposalApplyResource/reduceAssetDisposalInApply';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+  
+      contentType: 'application/json',
+  
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 保存填写表单信息页面
+export const saveThreeApi = params => {
+  const requestUrl = 'assetDisposalApplyResource/saveAssetDisposalThree';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+  
+      contentType: 'application/json',
+  
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 往处置申请单新增附报文件信息
+export const saveMaterialApi = params => {
+  const requestUrl = 'assetDisposalAttachmentMaterialResource/saveAssetDisposalAttachmentMaterial';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+  
+      contentType: 'application/json',
+  
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 查询申请单表单信息
+export const queryThree = id => {
+  const requestUrl = `assetDisposalApplyResource/queryByApplyIdInThree?assetDisposalApplyId=${id}`;
+  
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+  
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 根据处置申请单id查询其有的附报文件信息
+export const queryAttachmentApi = id => {
+  const requestUrl = `assetDisposalAttachmentMaterialResource/queryDisposalApplyHasAttachment?assetDisposalApplyId=${id}`;
+  
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+  
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 根据申请单id查询申请单状态
+export const queryStatusApi = id => {
+  const requestUrl = `assetDisposalApplyResource/queryApplyStatus?assetDisposalApplyId=${id}`;
+  
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+  
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 查询资产统计表数据
+export const queryTableApi = id => {
+  const requestUrl = `assetDisposalApplyResource/queryApplyStatisticalTable?assetDisposalApplyId=${id}`;
+  
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+  
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 查询处置汇总表
+export const querySummaryApi = id => {
+  const requestUrl = `assetDisposalApplyResource/queryApplySummary?assetDisposalApplyId=${id}`;
+  
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+  
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};

+ 346 - 0
src/assetsDisposal/assetConfig.js

@@ -0,0 +1,346 @@
+
+// 资产类型列名
+export const typeColumn = [
+  {
+    title: '申报单号',
+    dataIndex: 'documentNo',
+  },
+  {
+    title: '处置方式',
+    dataIndex: 'disposalWay',
+  },
+  {
+    title: '处置数量',
+    dataIndex: 'quantity',
+  },
+  {
+    title: '处置金额',
+    dataIndex: 'disposalAmount',
+  },
+  {
+    title: '流动资产',
+    dataIndex: 'currentAssets',
+  },
+  {
+    title: '固定资产',
+    dataIndex: 'fixedAssets',
+  },
+  {
+    title: '对外投资',
+    dataIndex: 'outboundInvestment',
+  },
+  {
+    title: '无形资产',
+    dataIndex: 'intangibleAssets',
+  },
+  {
+    title: '负债',
+    dataIndex: 'liabilities',
+  },
+  {
+    title: '业务操作',
+    dataIndex: 'operation',
+  },
+].map(item => ({ ...item, width: 100, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 中介机构列名
+export const natureColumn = [
+  {
+    title: '序号',
+    dataIndex: 'index',
+    key: 'index',
+    width: 50,
+    customRender: ({ text, record, index }) => `${index + 1}`,
+  },
+  {
+    title: '中介机构名称',
+    dataIndex: 'name',
+    width: 400,
+  },
+  {
+    title: '联系电话',
+    dataIndex: 'telephoneNum',
+    width: 300,
+  },
+  {
+    title: '联系人',
+    dataIndex: 'contactsName',
+    width: 300,
+  },
+  {
+    title: '地址',
+    dataIndex: 'address',
+    width: 300,
+  },
+  {
+    title: '综合评分',
+    dataIndex: 'score',
+    width: 100,
+  },
+
+].map(item => ({ ...item, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 中介机构列名
+export const orgColumn = [
+  {
+    title: '中介机构名称',
+    dataIndex: 'name',
+    width: 180,
+  },
+  {
+    title: '中介机构性质',
+    dataIndex: 'name',
+    width: 180,
+  },
+  {
+    title: '联系电话',
+    dataIndex: 'telephoneNum',
+    width: 120,
+  },
+  {
+    title: '联系人',
+    dataIndex: 'contactsName',
+    width: 120,
+  },
+  {
+    title: '评估(鉴证)号',
+    dataIndex: 'evaluationNumber',
+    width: 160,
+  },
+  {
+    title: '评估(鉴证)价值',
+    dataIndex: 'evaluateValue',
+    width: 160,
+  },
+  {
+    title: '中介费用(元)',
+    dataIndex: 'intermediaryFees',
+    width: 160,
+  },
+  {
+    title: '操作',
+    dataIndex: 'operation',
+    width: 70,
+  },
+].map(item => ({ ...item, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 资产详情列名
+export const assetColumn = [
+  {
+    title: '序号',
+    dataIndex: 'index',
+    key: 'index',
+    width: 50,
+    customRender: ({ text, record, index }) => `${index + 1}`,
+  },
+  {
+    title: '资产分类代码',
+    dataIndex: 'assetCategoryNo',
+    width: 120,
+  },
+  {
+    title: '资产编号',
+    dataIndex: 'assetInstanceNo',
+    width: 100,
+
+  },
+  {
+    title: '资产名称',
+    dataIndex: 'assetInstanceName',
+    width: 100,
+  },
+  {
+    title: '规格型号',
+    dataIndex: 'assetInstanceType',
+    width: 100,
+  },
+  {
+    title: '明细类别',
+    dataIndex: 'detailCategory',
+    width: 100,
+  },
+  {
+    title: '购置日期',
+    dataIndex: 'buyDate',
+    width: 70,
+  },
+  {
+    title: '处置数量',
+    dataIndex: 'disposalQuantity',
+    width: 80,
+  },
+  {
+    title: '原值(元)',
+    dataIndex: 'orginalValue',
+    width: 80,
+  },
+  {
+    title: '累计折旧',
+    dataIndex: 'address',
+    width: 80,
+  },
+  {
+    title: '净值',
+    dataIndex: 'netValue',
+    width: 80,
+  },
+  {
+    title: '评估(鉴证)价值',
+    dataIndex: 'evaluateValue',
+    width: 120,
+  },
+
+].map(item => ({ ...item, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 表单信息
+export const formConfig = [{
+  label: '处置方式',
+  type: 'span',
+  isRequired: false,
+  isLine: false,
+  key: 'disposalWay',
+}, {
+  label: '经办人',
+  type: 'input',
+  isRequired: true,
+  isLine: false,
+  key: 'operatorName',
+}, {
+  label: '联系电话',
+  type: 'input',
+  isRequired: true,
+  isLine: false,
+  key: 'operatorNum',
+}, {
+  label: '文号',
+  type: 'input',
+  isRequired: true,
+  isLine: false,
+  key: 'documentNumber',
+}, {
+  label: '单位申请文件名称',
+  type: 'input',
+  isRequired: true,
+  isLine: false,
+  key: 'applyFileName',
+}, {
+  label: '责任人',
+  type: 'input',
+  isRequired: true,
+  isLine: false,
+  key: 'responsibilityName',
+}, {
+  label: '转让/置换名称',
+  type: 'input',
+  isRequired: false,
+  isLine: true,
+  key: 'transferReplacementName',
+}, {
+  label: '处置原因',
+  type: 'textArea',
+  isRequired: false,
+  isLine: true,
+  key: 'disposalReason',
+}, {
+  label: '接收方名称',
+  type: 'input',
+  isRequired: false,
+  isLine: true,
+  key: '',
+}, {
+  label: '接收方性质',
+  type: 'select',
+  isRequired: false, 
+  isLine: false,
+  key: 'nature',
+}, {
+  label: '接收方组织机构代码',
+  type: 'input',
+  isRequired: false,
+  isLine: false,
+  key: 'organizationCode',
+}, {
+  label: '是否公车改革',
+  type: 'select',
+  isRequired: false,
+  isLine: false,
+  key: 'reform',
+}];
+
+// 处置资产统计表列名
+export const statisticsColumn = [
+  {
+    title: '项目',
+    dataIndex: 'projectName',
+    key: 'projectName',
+    width: 100,
+  },
+  {
+    title: '账目价值',
+    width:400,
+    children: [
+      {
+        title: '原值',
+        dataIndex: 'originalValue',
+        key: 'originalValue',
+        align: 'center', 
+        width: 200,
+      },
+      {
+        title: '净值',
+        dataIndex: 'netWorth',
+        key: 'netWorth',
+        align: 'center',
+        width: 200,
+      },
+    ],
+  },
+  {
+    title: '评估(鉴证)价值',
+    dataIndex: 'evaluateValue',
+    key: 'evaluateValue',
+    width: 200,
+  },
+
+].map(item => ({ ...item, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 附报材料列名
+export const materialsColumn = [
+  {
+    title: '序号',
+    dataIndex: 'index',
+    key: 'index',
+    width: 75,
+    customRender: ({ text, record, index }) => `${index + 1}`,
+  },
+  {
+    title: '文件名',
+    dataIndex: 'fileName',
+    key: 'fileName',
+  },
+].map(item => ({ ...item, ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 处置汇总表列名
+export const summaryColumn = [
+
+  {
+    title: '资产分类',
+    dataIndex: 'assetType',
+  },
+  {
+    title: '明细资产',
+    dataIndex: 'assetCategory',
+  },
+  {
+    title: '数量',
+    dataIndex: 'quantity',
+  },
+  {
+    title: '处置方式',
+    dataIndex: 'disposalWay',
+  },
+  {
+    title: '总价(元)',
+    dataIndex: 'totalValue',
+  },
+].map(item => ({ ...item,width:120, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));

+ 84 - 0
src/executeAssetDisposal/AssetDetail.vue

@@ -0,0 +1,84 @@
+<template>
+  <CommonTable ref="typeTable" :have-page="false" :columns="assetColumns" :data-source="assetDatas">
+    <template #title>资产详情</template>
+    <template #bodyCell="{ column }">
+      <template v-if="column.dataIndex === 'operation'">
+        <a-button type="link">资产明细</a-button>
+      </template>
+    </template>
+  </CommonTable>
+</template>
+
+<script setup>
+import { queryByIdApi } from './api.js';
+import Common from '../common/Common.js';
+import { message } from 'ant-design-vue';
+import { assetColumn } from './assetConfig.js';
+import { ref, defineProps, defineEmits, watch } from 'vue';
+import CommonTable from '../assetsDisposal/AssetCommonTable.vue';
+
+const emits = defineEmits(['getEvaluateValue']);
+
+const props = defineProps({
+  disposalId: {
+    type: String,
+    default: null,
+  },
+  selectAssetIds: {
+    type: Array,
+    default: () => [],
+  },
+  isReadonly: {
+    type: Boolean,
+    default: false,
+  },
+  readDatas: {
+    type: Object,
+    default: null,
+  },
+});
+
+const assetDatas = ref([]);
+const assetColumns = ref(assetColumn);
+
+
+// 查询资产详情
+const queryAsset = () => {
+  const params = {
+    ids: props.selectAssetIds,
+    recordId: props.disposalId,
+  };
+  queryByIdApi(params).then(
+    success => {
+      if (success.errorCode === 0) {
+        const { approvalAmount, choiceDisposedAmount, evaluateValue } = success.data;
+        if (approvalAmount !== null && approvalAmount !== undefined) success.data.approvalAmount = approvalAmount.toFixed(2);
+        if (choiceDisposedAmount !== null && choiceDisposedAmount !== undefined) success.data.choiceDisposedAmount = choiceDisposedAmount.toFixed(2);
+        if (evaluateValue !== null && evaluateValue !== undefined) success.data.evaluateValue = evaluateValue.toFixed(2);
+        assetDatas.value = [success.data];
+        emits('getEvaluateValue', success.data.evaluateValue);
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+watch(() => props.disposalId, (newValue, oldValue) => {
+  if (newValue !== oldValue) {
+    if (!props.isReadonly) {
+      queryAsset();
+    } else {
+      if (props.readDatas) {
+        assetDatas.value = [props.readDatas.assetDetailsVo];
+      }
+    }
+  }
+}, { immediate: true });
+
+</script>
+
+<style scoped></style>

+ 211 - 0
src/executeAssetDisposal/AssetsDisposal.vue

@@ -0,0 +1,211 @@
+<template>
+  <Navbar title="资产处置-执行处置" :is-go-back="true" />
+  <a-row style="display: flex;justify-content: space-between;align-items: center;">
+    <a-col :span="10">
+      <a-steps :current="current" size="small" type="navigation" :style="stepStyle" :items="steps" />
+    </a-col>
+    <a-col v-show="!isReadonly">
+      <a-button v-if="current > 0" style="margin-right: 8px" @click="prev">上一步</a-button>
+      <a-button v-if="current < steps.length - 1 && current !== 0" type="primary" @click="next">下一步</a-button>
+      <a-button v-if="current === 0" type="primary" @click="next">执行</a-button>
+      <a-button v-if="current == steps.length - 1" style="margin-right: 8px" type="primary" @click="saveForm(false)">
+        保存
+      </a-button>
+      <a-button v-if="current == steps.length - 1" type="primary" @click="saveForm(true)">
+        送财务登账
+      </a-button>
+    </a-col>
+  </a-row>
+  <AssetDetail
+    v-if="current !== 0" :disposal-id="disposalId" :select-asset-ids="selectAssetIds"
+    :is-readonly="isReadonly" :read-datas="disposalDatas" @get-evaluate-value="getEvaluateValue"
+  />
+  <keep-alive>
+    <DisposalStep1 v-if="current === 0" ref="disposal1" :disposal-id="disposalId" />
+  </keep-alive>
+  <keep-alive>
+    <DisposalStep2 v-if="current === 1" @get-acceptor="getAcceptor" @get-disposal-form="getDisposalForm" />
+  </keep-alive>
+  <keep-alive>
+    <DisposalStep3
+      v-if="current === 2" :disposal-id="disposalId" :acceptor-info="acceptorInfo"
+      :disposal-form="disposalForm" :is-operation="false"
+    />
+  </keep-alive>
+  <keep-alive>
+    <DisposalStep4
+      v-if="current === 3" ref="disposal4" :disposal-id="disposalId" :evaluate-value="evaluateValue"
+      :is-readonly="isReadonly" :read-datas="disposalDatas" :acceptor-info="acceptorInfo"
+      :disposal-form="disposalForm"
+    />
+  </keep-alive>
+</template>
+
+<script setup>
+import { onMounted, ref } from 'vue';
+import { Uuid } from 'pc-component-v3';
+import Common from '../common/Common';
+import { message } from 'ant-design-vue';
+import AssetDetail from './AssetDetail.vue';
+import DisposalStep1 from './DisposalStep1.vue';
+import DisposalStep2 from './DisposalStep2.vue';
+import DisposalStep3 from './DisposalStep3.vue';
+import DisposalStep4 from './DisposalStep4.vue';
+import { saveDisposalApi, queryByRecordIdApi } from './api.js';
+
+
+const current = ref(0);
+
+const selectAssetIds = ref([]); // 所选资产Id
+
+const disposalId = ref(''); // 处置单Id
+
+const disposal1 = ref();
+const disposal4 = ref();
+
+const isReadonly = ref(false);
+
+const disposalDatas = ref(null);
+
+const acceptorInfo = ref(null); // 所选买受方数据
+const evaluateValue = ref(null); // 评估价值总额,收益金额
+const disposalForm = ref(null); // 所选处置形式
+
+onMounted(() => {
+  disposalId.value = getQueryParams().disposalId;
+  queryByRecordId();
+});
+
+// 获取评估价值
+const getEvaluateValue = value => {
+  evaluateValue.value = value;
+};
+
+// 获取所选买受方信息
+const getAcceptor = info => {
+  acceptorInfo.value = info;
+};
+
+// 获取处置形式
+const getDisposalForm = info => {
+  disposalForm.value = info;
+};
+
+const next = () => {
+  if (current.value === 0) {
+    selectAssetIds.value = disposal1.value.getSelected();
+    if (!selectAssetIds.value.length) {
+      message.warning('请您先选择待处置资产。');
+      return;
+    }
+  }
+  if (current.value === 1) {
+    if (!acceptorInfo.value) {
+      message.warning('请您先添加买受方。');
+      return;
+    }
+    if (!disposalForm.value) {
+      message.warning('请您先选择处置形式。');
+      return;
+    }
+  }
+  if (current.value === 2) {
+    if (!acceptorInfo.value.quotation) {
+      message.warning('请您先填写买受方报价并将其勾选。');
+      return;
+    }
+  }
+  current.value++;
+};
+
+const prev = () => {
+  current.value--;
+};
+
+// 查询执行单数据
+const queryByRecordId = () => {
+  queryByRecordIdApi(disposalId.value).then(
+    success => {
+      if (success.errorCode === 0) {
+        if (success.data) {
+          current.value = 3;
+          // const { assetDetailsVo, flag, innerBuyerVo, revenueSubmissionVo } = success.data;
+          success.data.flag ? isReadonly.value = false : isReadonly.value = true;
+          disposalDatas.value = success.data;
+        }
+      } else {
+        message.warning(success.errorMessage, 5);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+const saveForm = isRegistered => {
+  const saveDatas = {
+    ...disposal4.value.earningsDatas[0],
+    recordId: disposalId.value,
+    ids: selectAssetIds.value,
+    dispositionType: disposalForm.value.value,
+    buyerId: acceptorInfo.value.id,
+    quotation: acceptorInfo.value.quotation,
+    registered: isRegistered,
+  };
+  delete saveDatas.anticipatedIncome;
+  saveDisposal(saveDatas);
+};
+
+// 保存执行单
+const saveDisposal = params => {
+  saveDisposalApi(params).then(
+    success => {
+      if (success.errorCode === 0) {
+        message.success('资产处置单执行成功。');
+        window.open(
+          '/#/desktop/window1/20241101_113732' + '?uuid=' + Uuid.createUUID(),
+          '_self',
+        );
+      } else {
+        message.warning(success.errorMessage, 5);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+
+// 获取单据Id
+const getQueryParams = () => {
+  const url = window.location.href;
+  let urlStr = url.split('?')[1];
+  const urlSearchParams = new URLSearchParams(urlStr);
+  const result = Object.fromEntries(urlSearchParams.entries());
+  return result;
+};
+
+const steps = [
+  {
+    title: '选择待处置资产',
+  },
+  {
+    title: '选择买受方',
+  },
+  {
+    title: '买受方报价',
+  },
+  {
+    title: '处置执行完成',
+  },
+];
+
+const stepStyle = {
+  marginBottom: '8px',
+  boxShadow: '0px -1px 0 0 #e8e8e8 inset',
+};
+</script>
+
+<style scoped></style>

+ 79 - 0
src/executeAssetDisposal/DisposalStep1.vue

@@ -0,0 +1,79 @@
+<template>
+  <div style="position: relative;">
+    <span style="position: absolute;top: 1.5rem;left: 32rem;color: red;">处置方式:{{ disposalWay }}</span>
+    <InfoWindow
+      v-if="disposalId" ref="infoWindowRef" :info-window-no="infoWindowNo"
+      :where-clause-source="whereClauseSource" :multiple="true" :is-search-widget="true"
+    />
+  </div>
+</template>
+
+<script setup>
+import { queryById } from './api.js';
+import Common from '../common/Common.js';
+import { message } from 'ant-design-vue';
+import { ref, defineProps, defineExpose, watch } from 'vue';
+
+const props = defineProps({
+  disposalId: {
+    type: String,
+    default: null,
+  },
+});
+
+const disposalWay = ref('');
+const infoWindowRef = ref();
+const whereClauseSource = ref('');
+const infoWindowNo = ref('20241101_160846');
+
+// 获取所选资产
+const getSelected = () => {
+  const modelDatas = infoWindowRef.value.getSelectedModelDatas();
+  const assetIds = modelDatas.map(item => {
+    return item.id;
+  });
+  return assetIds;
+};
+
+// 查询资产类型
+const queryAsset = () => {
+  queryById(props.disposalId).then(
+    success => {
+      if (success.errorCode === 0) {
+        disposalWay.value = success.data.disposalWay;
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+watch(() => props.disposalId, newValue => {
+  if (newValue) {
+    queryAsset();
+    whereClauseSource.value = { customWhere: '(isApproved is null or isApproved = 0) and adpa.id = ' + newValue };
+  }
+}, { immediate: true });
+
+defineExpose({
+  getSelected,
+});
+
+</script>
+
+<style scoped>
+:deep(.ant-page-header-heading) {
+  display: none !important;
+}
+
+:deep(.m-segmented) {
+  display: none !important;
+}
+
+:deep(.flex-header) {
+  flex: 0 0 40px !important;
+}
+</style>

+ 64 - 0
src/executeAssetDisposal/DisposalStep2.vue

@@ -0,0 +1,64 @@
+<template>
+  <div>
+    <CommonTable :have-page="false" :columns="acceptorColumns" :data-source="acceptorDatas">
+      <template #title>
+        <div><span>选择买受方</span></div>
+        <a-divider style="margin: 8px 0;" />
+        <a-flex justify="space-between" align="center">
+          <a-space>
+            <a-button size="small" :icon="h(PlusCircleTwoTone)" @click="openAdd = true">添加买受方</a-button>
+            <span>处置形式:</span>
+            <a-select
+              v-model:value="disposalForm" size="small" :options="disposalForms"
+              style="width: 150px;" @change="disposalFormChanged"
+            />
+          </a-space>
+        </a-flex>
+      </template>
+      <template #bodyCell="{ column }">
+        <template v-if="column.dataIndex === 'operation'">
+          <a-button type="link" @click="deleteAcceptor">删除</a-button>
+        </template>
+      </template>
+    </CommonTable>
+  </div>
+  <component :is="SelectAcceptor" v-if="openAdd" v-model:open="openAdd" @get-select-info="getSelectInfo" />
+</template>
+
+<script setup>
+import { ref, defineEmits, h } from 'vue';
+import SelectAcceptor from './SelectAcceptor.vue';
+import { PlusCircleTwoTone } from '@ant-design/icons-vue';
+import CommonTable from '../assetsDisposal/AssetCommonTable.vue';
+import { acceptorColumn, disposalFormDatas } from './assetConfig.js';
+
+const emits = defineEmits(['getAcceptor','getDisposalForm']);
+
+const openAdd = ref(false);
+
+const disposalForm = ref(undefined);
+const disposalForms = ref(disposalFormDatas);
+
+const acceptorDatas = ref([]);
+const acceptorColumns = ref(acceptorColumn);
+
+// 获取买受方信息
+const getSelectInfo = info => {
+  acceptorDatas.value = [info];
+  emits('getAcceptor',info);
+};
+
+// 删除所选买受方
+const deleteAcceptor = () => {
+  acceptorDatas.value = [];
+  emits('getAcceptor',null);
+};
+
+// 获取处置形式
+const disposalFormChanged = (_,disposalForm) => {
+  emits('getDisposalForm',disposalForm);
+};
+
+</script>
+
+<style scoped></style>

+ 86 - 0
src/executeAssetDisposal/DisposalStep3.vue

@@ -0,0 +1,86 @@
+<template>
+  <div>
+    <CommonTable
+      :is-select="!isOperation" :is-checkbox="false" :is-disabled="isReadonly" :have-page="false"
+      :columns="quoteColumns" :data-source="quoteDatas" @get-selected="getSelectedInfo"
+    >
+      <template #title>
+        <div><span>买受方报价</span></div>
+        <a-divider style="margin: 8px 0;" />
+        <span>处置形式:{{ disposalForm ? disposalForm.label : disposalFormData }}</span>
+      </template>
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.dataIndex === 'quotation' && !isOperation">
+          <a-input-number v-model:value="record.quotation" :controls="false" :step="0.01" style="width: 100%;" />
+        </template>
+        <template v-if="column.dataIndex === 'operation'">
+          <a-button type="link">评价</a-button>
+        </template>
+      </template>
+    </CommonTable>
+  </div>
+</template>
+
+<script setup>
+import { quoteColumn } from './assetConfig.js';
+import CommonTable from '../assetsDisposal/AssetCommonTable.vue';
+import { ref, defineProps, watch, computed, defineEmits } from 'vue';
+
+const emits = defineEmits(['getAcceptor']);
+const props = defineProps({
+  acceptorInfo: {
+    type: Object,
+    default: null,
+  },
+  disposalForm: {
+    type: Object,
+    default: null,
+  },
+  isOperation: {
+    type: Boolean,
+    default: true,
+  },
+  isReadonly: {
+    type: Boolean,
+    default: false,
+  },
+  readDatas: {
+    type: Object,
+    default: null,
+  },
+});
+
+const quoteDatas = ref([]);
+// const quoteColumns = ref(quoteColumn);
+const disposalFormData = ref('');
+
+const quoteColumns = computed(() => {
+  if (!props.isOperation) {
+    return quoteColumn.filter(item => item.dataIndex != 'operation');
+  } else {
+    return quoteColumn;
+  }
+});
+
+const getSelectedInfo = info => {
+  emits('getAcceptor', info.selectedRows[0]);
+};
+
+watch(() => props.acceptorInfo, newValue => {
+  if (newValue) {
+    quoteDatas.value = [newValue];
+  }
+}, { immediate: true });
+
+watch(() => props.readDatas, newValue => {
+  if (newValue) {
+    quoteDatas.value = [newValue.innerBuyerVo];
+    if(!props.disposalForm){
+      disposalFormData.value = newValue.assetDetailsVo.disposalWay;
+    }
+  }
+}, { immediate: true });
+
+</script>
+
+<style scoped></style>

+ 78 - 0
src/executeAssetDisposal/DisposalStep4.vue

@@ -0,0 +1,78 @@
+<template>
+  <div>
+    <CommonTable :have-page="false" :columns="earningsColumns" :data-source="earningsDatas">
+      <template #title>
+        <div><span>收益登记</span></div>
+      </template>
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.dataIndex !== 'expectedRevenue'">
+          <template v-if="column.isInput">
+            <a-input v-model:value="record[column.dataIndex]" :disabled="isReadonly" />
+          </template>
+          <template v-else>
+            <a-input-number
+              v-model:value="record[column.dataIndex]" :disabled="isReadonly" :controls="false"
+              :step="0.01" style="width: 100%;"
+            />
+          </template>
+        </template>
+      </template>
+    </CommonTable>
+    <DisposalStep3 :acceptor-info="acceptorInfo" :disposal-form="disposalForm" :is-operation="true" :is-readonly="isReadonly" :read-datas="readDatas" />
+  </div>
+</template>
+
+<script setup>
+import DisposalStep3 from './DisposalStep3.vue';
+import { earningsColumn } from './assetConfig.js';
+import CommonTable from '../assetsDisposal/AssetCommonTable.vue';
+import { ref, defineProps, watch, defineEmits, defineExpose } from 'vue';
+
+const emits = defineEmits(['getAcceptor']);
+const props = defineProps({
+  evaluateValue: {
+    type: String,
+    default: null,
+  },
+  acceptorInfo: {
+    type: Object,
+    default: null,
+  },
+  disposalForm: {
+    type: Object,
+    default: null,
+  },
+  isReadonly: {
+    type: Boolean,
+    default: false,
+  },
+  readDatas: {
+    type: Object,
+    default: null,
+  },
+});
+
+const earningsDatas = ref([]);
+const earningsColumns = ref(earningsColumn);
+
+watch(() => props.evaluateValue, newValue => {
+  if (newValue) {
+    earningsDatas.value = [{
+      expectedRevenue: newValue,
+      description: '',
+    }];
+  }
+}, { immediate: true });
+
+watch(() => props.readDatas, newValue => {
+  if (newValue) {
+    earningsDatas.value = [newValue.revenueSubmissionVo];
+  }
+}, { immediate: true });
+
+defineExpose({
+  earningsDatas,
+});
+</script>
+
+<style scoped></style>

+ 238 - 0
src/executeAssetDisposal/SelectAcceptor.vue

@@ -0,0 +1,238 @@
+<template>
+  <a-modal
+    :open="open" :mask-closable="false" ok-text="确认" cancel-text="取消" title="选择买受方" width="60%"
+    @update:open="$emit('update:open', $event)" @cancel="cancelSelect" @ok="confirmEdit"
+  >
+    <a-card>
+      <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
+        <a-button type="link" :icon="h(PlusCircleTwoTone)" @click="handleAddRow">新增</a-button>
+        <a-input-search
+          v-model:value="searchQuery" style="width: 300px;" placeholder="请输入买受方,电话,联系人进行查询" enter-button
+          @search="handleSearch"
+        />
+      </div>
+      <div style="height: 240px;">
+        <a-table
+          :columns="acceptorColumns" :data-source="acceptorDatas" row-key="id" bordered :pagination="false"
+          size="small" row-class-name="editable-row" :scroll="{ y: 220 }" :row-selection="{
+            type: 'radio',
+            onChange: rowSelectedChange,
+            selectedRowKeys: selectedKey,
+          }"
+        >
+          <template #bodyCell="{ column, record, text, index }">
+            <template v-if="column.dataIndex === 'operation'">
+              <span v-if="record.isEditing">
+                <a-button type="link" @click="handleSaveRow(record, index)">保存</a-button>
+                <a-button type="link" danger @click="handleCancelRow(record, index)">取消</a-button>
+              </span>
+              <span v-else>
+                <a-button type="link" @click="handleEditRow(record, index, true)">编辑</a-button>
+                <a-button type="link" danger @click="handleCancelRow(record, index, true)">删除</a-button>
+              </span>
+            </template>
+            <template v-else>
+              <a-input v-if="record.isEditing" v-model:value="record[column.dataIndex]" size="small" />
+              <span v-else>{{ text }}</span>
+            </template>
+          </template>
+        </a-table>
+      </div>
+    </a-card>
+
+    <a-card style="margin-top: 8px;">
+      <span>该买受方评价</span>
+      <div style="height: 240px;">
+        <a-table
+          :columns="evaluateColumns" :data-source="evaluateData" row-key="id" bordered :pagination="false"
+          size="small" :scroll="{ y: 220 }"
+        />
+      </div>
+    </a-card>
+  </a-modal>
+</template>
+
+<script setup>
+import { message } from 'ant-design-vue';
+import Common from '../common/Common.js';
+import { queryAllApi, saveBuyerApi } from './api.js';
+import { PlusCircleTwoTone } from '@ant-design/icons-vue';
+import { ref, defineEmits, defineProps, h, onMounted } from 'vue';
+import { acceptorAddColumn, evaluateColumn } from './assetConfig.js';
+
+
+const emit = defineEmits(['update:open', 'getSelectInfo']);
+const props = defineProps({
+  open: {
+    type: Boolean,
+    default: false,
+  },
+});
+
+const acceptorColumns = ref(acceptorAddColumn);
+
+const acceptorDatas = ref([]); // 买受方数据
+const searchQuery = ref(''); // 查询参数
+
+const selectedKey = ref([]); // 所选key值
+const selectInfo = ref(null); // 所选数据
+const evaluateData = ref([]); // 评价数据
+
+// 选择买受方变化
+const rowSelectedChange = (key, record) => {
+  selectedKey.value = key;
+  selectInfo.value = JSON.parse(JSON.stringify(record))[0];
+};
+
+// 关闭选择买受方
+const cancelSelect = () => {
+  emit('update:open', false);
+};
+
+// 确认选择买受方
+const confirmEdit = () => {
+  emit('update:open', false);
+  emit('getSelectInfo', selectInfo.value);
+};
+
+// 查询
+const handleSearch = searchValue => {
+  searchAcceptor(searchValue);
+};
+
+// 添加一行新数据
+const handleAddRow = () => {
+  acceptorDatas.value.push({
+    buyerName: '',
+    phone: '',
+    contactPerson: '',
+    mainBusiness: '',
+    address: '',
+    isEditing: true,
+  });
+};
+
+// 编辑行数据
+const handleEditRow = record => {
+  record.isEditing = true;
+};
+
+// 保存行数据
+const handleSaveRow = record => {
+  if (!record.buyerName) {
+    message.warning('请输入买受方名称。');
+    return;
+  }
+  if (!record.phone) {
+    message.warning('请输入联系电话。');
+    return;
+  }
+  if (!record.contactPerson) {
+    message.warning('请输入联系人。');
+    return;
+  }
+  if (!record.mainBusiness) {
+    message.warning('请输入主营业务。');
+    return;
+  }
+  if (!record.address) {
+    message.warning('请输入地址。');
+    return;
+  }
+  addAcceptor(record);
+};
+
+// 取消编辑,并删除该行  
+const handleCancelRow = (record, index, isDelete) => {
+  acceptorDatas.value.splice(index, 1);
+  if (isDelete) deleteAcceptor(record.id);
+};
+
+onMounted(() => {
+  searchAcceptor('');
+});
+
+// 查询买受方
+const searchAcceptor = str => {
+  queryAllApi(str).then(
+    success => {
+      if (success.errorCode === 0) {
+        if (success.data) {
+          acceptorDatas.value = success.data;
+        }
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+
+
+};
+
+// 新增买受方
+const addAcceptor = record => {
+  const params = {
+    ...record,
+  };
+  saveBuyerApi(params).then(
+    success => {
+      if (success.errorCode === 0) {
+        message.success('新增买受方成功。');
+        record.isEditing = false;
+        searchAcceptor('');
+      } else {
+        message.warning(success.errorMessage);
+      }
+    },
+    error => {
+      Common.processException(error);
+    },
+  );
+};
+
+// 删除买受方
+const deleteAcceptor = id => {
+  $.ajax({
+    url: Common.getApiURL('AcceptorResource/deleteAcceptor'),
+    type: 'post',
+    data: {
+      AcceptorId: id,
+    },
+
+    beforeSend: function (request) {
+      Common.addTokenToRequest(request);
+    },
+    success: function (data) {
+      if (data.errorCode === 0) {
+        message.success('删除成功');
+        searchAcceptor('');
+      } else {
+        message.warning(data.errorMessage);
+      }
+    },
+    error: function (XMLHttpRequest, textStatus, errorThrown) {
+      Common.processException(XMLHttpRequest);
+    },
+  });
+};
+
+
+const evaluateColumns = ref(evaluateColumn);
+</script>
+
+<style scoped>
+.editable-row .ant-table-tbody>tr>td {
+  transition: background 0.3s;
+}
+
+.editable-row .ant-table-tbody>tr.editing>td {
+  background: #f5f5f5;
+}
+
+:deep(.ant-card-body) {
+  padding: 12px;
+}
+</style>

+ 142 - 0
src/executeAssetDisposal/api.js

@@ -0,0 +1,142 @@
+import Common from '../common/Common';
+
+// 根据处置单id和选择处置的资产id查询信息
+export const queryByIdApi = params => {
+  const requestUrl = 'assetExecuteDisposalResource/queryByAssetDisposalId';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+
+      contentType: 'application/json',
+
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 根据id查询资产处置申请单
+export const queryById = id => {
+  const requestUrl = `assetDisposalApplyResource/queryByAssetDisposalApplyId?assetDisposalApplyId=${id}`;
+
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 查询买受方信息
+export const queryAllApi = condition => {
+  const requestUrl = `buyerResource/queryAll?condition=${condition}`;
+
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 根据处置单id和选择处置的资产id查询信息
+export const saveBuyerApi = params => {
+  const requestUrl = 'buyerResource/saveBuyer';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+
+      contentType: 'application/json',
+
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 根据处置单id和选择处置的资产id查询信息
+export const saveDisposalApi = params => {
+  const requestUrl = 'assetExecuteDisposalResource/saveByAssetDisposal';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+
+      contentType: 'application/json',
+
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 查询资产处置申请单的执行处置单
+export const queryByRecordIdApi = id => {
+  const requestUrl = `assetExecuteDisposalResource/queryByRecordId?recordId=${id}`;
+
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};

+ 261 - 0
src/executeAssetDisposal/assetConfig.js

@@ -0,0 +1,261 @@
+
+
+// 资产详情列名
+export const assetColumn = [
+
+  {
+    title: '申报单号',
+    dataIndex: 'declarationNumber',
+  },
+  {
+    title: '处置方式',
+    dataIndex: 'disposalWay',
+
+  },
+  {
+    title: '批复单号',
+    dataIndex: 'approvalOrderNumber',
+  },
+  {
+    title: '批复数量',
+    dataIndex: 'approvalQuantity',
+  },
+  {
+    title: '批复金额',
+    dataIndex: 'approvalAmount',
+  },
+  {
+    title: '选择处置数量',
+    dataIndex: 'choiceDisposedQuantity',
+  },
+  {
+    title: '选择处置金额',
+    dataIndex: 'choiceDisposedAmount',
+  },
+  {
+    title: '评估价值',
+    dataIndex: 'evaluateValue',
+  },
+  {
+    title: '业务操作',
+    dataIndex: 'operation',
+  },
+].map(item => ({ ...item, width: 100, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 买受方列名
+export const acceptorColumn = [
+  {
+    title: '序号',
+    dataIndex: 'index',
+    key: 'index',
+    width: 50,
+    customRender: ({ text, record, index }) => `${index + 1}`,
+  },
+  {
+    title: '买受方名称',
+    dataIndex: 'buyerName',
+    width: 100,
+  },
+  {
+    title: '联系电话',
+    dataIndex: 'phone',
+    width: 100,
+  },
+  {
+    title: '联系人',
+    dataIndex: 'contactPerson',
+    width: 100,
+  },
+  {
+    title: '主营业务',
+    dataIndex: 'mainBusiness',
+    width: 100,
+  },
+  {
+    title: '地址',
+    dataIndex: 'address',
+    width: 100,
+  },
+  {
+    title: '好评率',
+    dataIndex: 'positiveRating',
+    width: 100,
+  },
+  {
+    title: '操作',
+    dataIndex: 'operation',
+    key: 'operation',
+    width: 100,
+  },
+
+].map(item => ({ ...item, width: 100, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 买受方列名-新增
+export const acceptorAddColumn = [
+  {
+    title: '买受方名称',
+    dataIndex: 'buyerName',
+  },
+  {
+    title: '联系电话',
+    dataIndex: 'phone',
+  },
+  {
+    title: '联系人',
+    dataIndex: 'contactPerson',
+  },
+  {
+    title: '主营业务',
+    dataIndex: 'mainBusiness',
+  },
+  {
+    title: '地址',
+    dataIndex: 'address',
+  },
+  {
+    title: '操作',
+    dataIndex: 'operation',
+    key: 'operation',
+  },
+
+].map(item => ({ ...item, width: 100, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+// 评价列名
+export const evaluateColumn = [
+  {
+    title: '维修时间',
+    dataIndex: 'date',
+    key: 'date',
+  },
+  {
+    title: '评价人',
+    dataIndex: 'user',
+    key: 'user',
+  },
+  {
+    title: '评价内容',
+    dataIndex: 'content',
+    key: 'content',
+  },
+];
+
+// 处置形式数据
+export const disposalFormDatas = [
+  {
+    value: 'Auction',
+    label: '拍卖',
+  },
+  {
+    value: 'Bidding',
+    label: '招投标',
+  },
+  {
+    value: 'Inquiry',
+    label: '询价',
+  },
+  {
+    value: 'AgreementTransfer',
+    label: '协议转让',
+  },
+  {
+    value: 'Other',
+    label: '其他方式',
+  },
+];
+
+// 买受方报价
+export const quoteColumn = [
+  {
+    title: '序号',
+    dataIndex: 'index',
+    key: 'index',
+    width: 50,
+    customRender: ({ text, record, index }) => `${index + 1}`,
+  },
+  {
+    title: '买受方名称',
+    dataIndex: 'buyerName',
+    width: 200,
+  },
+  {
+    title: '联系电话',
+    dataIndex: 'phone',
+    width: 120,
+  },
+  {
+    title: '联系人',
+    dataIndex: 'contactPerson',
+    width: 100,
+  },
+  {
+    title: '地址',
+    dataIndex: 'address',
+    width: 150,
+  },
+  {
+    title: '主营业务',
+    dataIndex: 'mainBusiness',
+    width: 150,
+  },
+  {
+    title: '评价',
+    dataIndex: 'positiveRating',
+    width: 80,
+  },
+  {
+    title: '报价',
+    dataIndex: 'quotation',
+    width: 120,
+  },
+  {
+    title: '操作',
+    dataIndex: 'operation',
+    width: 120,
+  },
+
+].map(item => ({ ...item, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));
+
+
+// 收益登记列名
+export const earningsColumn = [
+  {
+    title: '合同编号',
+    dataIndex: 'contractNumber',
+    isInput:true,
+  },
+  {
+    title: '预计收益',
+    dataIndex: 'expectedRevenue',
+    isInput:false,
+  },
+  {
+    title: '实收金额',
+    dataIndex: 'actualRevenue',
+    isInput:false,
+  },
+  {
+    title: '评估鉴证费用',
+    dataIndex: 'appraisalFee',
+    isInput:false,
+  },
+  {
+    title: '税金',
+    dataIndex: 'taxAmount',
+    isInput:false,
+  },
+  {
+    title: '拍卖佣金',
+    dataIndex: 'auctionCommission',
+    isInput:false,
+  },
+  {
+    title: '其他费用',
+    dataIndex: 'otherExpenses',
+    isInput:false,
+  },
+  {
+    title: '备注',
+    dataIndex: 'description',
+    isInput:true,
+  },
+].map(item => ({ ...item, width: 100, align: 'center', ellipsis: true, resizable: true, maxWidth: 300, minWidth: 75 }));

+ 4 - 0
src/index.js

@@ -78,6 +78,8 @@ import CurdWindow1 from './window1/CurdWindow.vue';
 import CurdWindowModal from './window1/CurdWindowModal.vue';
 import AuthImage from './widget/AuthImage.vue';
 import ShortcutMenu from './dashboard/ShortcutMenu.vue';
+import AssetsDisposal from './assetsDisposal/AssetsDisposal.vue';
+import ExecuteAssetDisposal from './executeAssetDisposal/AssetsDisposal.vue';
 
 export {
   App,
@@ -146,4 +148,6 @@ export {
   CurdWindowModal,
   AuthImage,
   ShortcutMenu,
+  AssetsDisposal,
+  ExecuteAssetDisposal,
 };

+ 5 - 0
src/routes/main_routes.js

@@ -69,6 +69,9 @@ const SamlLogin = () => import('../client/SamlLogin.vue');
 const CasLogin = () => import('../client/CasLogin.vue');
 const PrinterConfiguration = () => import('../printer/PrinterConfiguration.vue');
 const ShortcutMenu = () => import('../dashboard/ShortcutMenu.vue');
+const AssetsDisposal = () => import('../assetsDisposal/AssetsDisposal.vue');
+const ExecuteAssetDisposal = () => import('../executeAssetDisposal/AssetsDisposal.vue');
+
 
 import { ProcessReport } from 'pc-component-v3';
 
@@ -123,6 +126,8 @@ export default [
 
       // 快捷菜单
       { path: 'shortcutMenu',name:'ShortcutMenu', component: ShortcutMenu },
+      { path: 'disposalApplication', component: AssetsDisposal },
+      { path: 'executeAssetDisposal', component: ExecuteAssetDisposal },
 
       // CRUD编辑窗口
       // eslint-disable-next-line