|
|
@@ -0,0 +1,434 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <a-row>
|
|
|
+ <a-col flex="15%" class="tree_box">
|
|
|
+ <a-tree
|
|
|
+ v-model:expandedKeys="expandedKeys" v-model:selectedKeys="selectedKeys"
|
|
|
+ :field-names="{ title: 'text', key: 'id' }" :tree-data="treeDatas" :show-line="true"
|
|
|
+ @select="categoriesSelected"
|
|
|
+ />
|
|
|
+ </a-col>
|
|
|
+ <a-col flex="auto" class="table_box" style="width: 0;">
|
|
|
+ <div class="operation_box">
|
|
|
+ <a-input-search
|
|
|
+ v-model:value="searchParams.name" size="small"
|
|
|
+ style="width: 300px;margin:0 0 8px 0;" enter-button @search="searchChange"
|
|
|
+ />
|
|
|
+ <a-pagination
|
|
|
+ v-model:current="current" simple size="small" :total="infoTotal"
|
|
|
+ :default-page-size="20" @change="getPageParams"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="operation_box">
|
|
|
+ <a-space>
|
|
|
+ <a-button size="small" :icon="h(FieldTimeOutlined)" @click="operation('设置折旧年限')">
|
|
|
+ 设置折旧年限
|
|
|
+ </a-button>
|
|
|
+ <a-button size="small" :icon="h(MoneyCollectOutlined)" @click="setDepreciation">
|
|
|
+ 设置计提折旧
|
|
|
+ </a-button>
|
|
|
+ <a-button size="small" :icon="h(PayCircleOutlined)" @click="cancelDepreciation">
|
|
|
+ 设置不提折旧
|
|
|
+ </a-button>
|
|
|
+ <a-button size="small" :icon="h(ProfileOutlined)" @click="operation('设置折旧方法')">
|
|
|
+ 设置折旧方法
|
|
|
+ </a-button>
|
|
|
+ <a-button size="small" :icon="h(PercentageOutlined)" @click="operation('设置残值率')">
|
|
|
+ 设置残值率
|
|
|
+ </a-button>
|
|
|
+ </a-space>
|
|
|
+ <a-space>
|
|
|
+ <!-- <a-button size="small" :icon="h(DownloadOutlined)">导出</a-button> -->
|
|
|
+ </a-space>
|
|
|
+ </div>
|
|
|
+ <CommonTable
|
|
|
+ ref="commonTable" :is-select="true" :selected-keys="selectedIds" :have-page="false"
|
|
|
+ :columns="columns" :data-source="dataSource" :top-right="true" :is-loading="isLoading"
|
|
|
+ @get-selected="getSelectColumn"
|
|
|
+ >
|
|
|
+ <template #bodyCell="{ column, record }">
|
|
|
+ <template v-if="column.dataIndex === 'reservedRate'">
|
|
|
+ <span v-if="record.reservedRate">{{ record.reservedRate }}%</span>
|
|
|
+ <span v-else />
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </CommonTable>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ <div class="footer_box">
|
|
|
+ <p>您所选的资产共计:<span style="color: red;">{{ selectedIds.length }}</span> 条</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <a-modal v-model:open="visible" width="26%" :title="modalTitle" @ok="setDepreciationInfo">
|
|
|
+ <a-form-item v-if="modalTitle === '设置折旧年限'" label="请输入" style="margin-top: 24px;">
|
|
|
+ <a-input-number v-model:value="yearLimit" :controls="false" addon-after="月" style="width: 90%;" />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item v-if="modalTitle === '设置折旧方法'" label="请选择" style="margin-top: 24px;">
|
|
|
+ <a-select
|
|
|
+ v-model:value="depreciationMethod" style="width: 90%" :options="depreciationMethods"
|
|
|
+ :field-names="{ label: 'text', value: 'id' }"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item v-if="modalTitle === '设置残值率'" label="请输入" style="margin-top: 24px;">
|
|
|
+ <a-input-number
|
|
|
+ v-model:value="reservedRate" :controls="false" :step="0.01" :min="0" :max="100"
|
|
|
+ :formatter="value => `${value}%`" :parser="value => value.replace('%', '')" style="width: 90%;"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ </a-modal>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, reactive, h } from 'vue';
|
|
|
+import Common from '../../common/Common';
|
|
|
+import CommonTable from '../../common/CommonTable.vue';
|
|
|
+import { FieldTimeOutlined, MoneyCollectOutlined, PayCircleOutlined, DownloadOutlined, ProfileOutlined, PercentageOutlined } from '@ant-design/icons-vue';
|
|
|
+import {
|
|
|
+ queryCategoriesApi, queryByNameApi, queryByIdApi, updateYearApi, updateExtractApi, getMethodsApi, updateMethodApi,
|
|
|
+ updateReservedRateApi,
|
|
|
+} from '../../api/assetPeriodDepreciate';
|
|
|
+import { infoColumns, debounce } from './util.js';
|
|
|
+import { message, Modal } from 'ant-design-vue';
|
|
|
+
|
|
|
+// 表格配置
|
|
|
+const commonTable = ref();
|
|
|
+const infoTotal = ref(0);
|
|
|
+const dataSource = ref([]);
|
|
|
+const columns = ref(infoColumns);
|
|
|
+const selectedIds = ref([]); // 用作表格选择的唯一key值
|
|
|
+const current = ref(1);
|
|
|
+// 树形配置
|
|
|
+const expandedKeys = ref([]);
|
|
|
+const selectedKeys = ref([]);
|
|
|
+const treeDatas = ref([]);
|
|
|
+// 折旧方法
|
|
|
+const depreciationMethod = ref('');
|
|
|
+const depreciationMethods = ref([]);
|
|
|
+
|
|
|
+const visible = ref(false);
|
|
|
+const modalTitle = ref('');
|
|
|
+const yearLimit = ref(null); // 折旧年限
|
|
|
+const reservedRate = ref(null); // 残值率
|
|
|
+const isLoading = ref(false);
|
|
|
+const isAllSearch = ref(true);
|
|
|
+const selectCategory = ref(null);
|
|
|
+const selectCategoryId = ref([]);
|
|
|
+
|
|
|
+// 查询参数
|
|
|
+const searchParams = reactive({
|
|
|
+ name: '',
|
|
|
+ range: {
|
|
|
+ start: 0,
|
|
|
+ length: 20,
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const clearDatas = () => {
|
|
|
+ modalTitle.value = '';
|
|
|
+ yearLimit.value = null;
|
|
|
+ reservedRate.value = null;
|
|
|
+ depreciationMethod.value = null;
|
|
|
+ visible.value = false;
|
|
|
+ selectedIds.value = [];
|
|
|
+ commonTable.value.clear();
|
|
|
+};
|
|
|
+
|
|
|
+// 打开模态框
|
|
|
+const operation = title => {
|
|
|
+ if (!selectedIds.value || selectedIds.value.length === 0) {
|
|
|
+ message.warning('请您至少选择一条分类数据。');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ modalTitle.value = title;
|
|
|
+ visible.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+// 设置折旧年限/折旧方法/残值率
|
|
|
+const setDepreciationInfo = () => {
|
|
|
+ if (modalTitle.value === '设置折旧年限') {
|
|
|
+ const params = {
|
|
|
+ usedYearLimit: yearLimit.value,
|
|
|
+ assetCategoryIds: selectedIds.value,
|
|
|
+ };
|
|
|
+ setYearLimit(params);
|
|
|
+ } else if (modalTitle.value === '设置折旧方法') {
|
|
|
+ const params = {
|
|
|
+ depreciationMethodId: depreciationMethod.value,
|
|
|
+ assetCategoryIds: selectedIds.value,
|
|
|
+ };
|
|
|
+ setMethod(params);
|
|
|
+ } else {
|
|
|
+ const params = {
|
|
|
+ reservedRate: reservedRate.value,
|
|
|
+ assetCategoryIds: selectedIds.value,
|
|
|
+ };
|
|
|
+ setReservedRate(params);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 设置折旧年限
|
|
|
+const setYearLimit = params => {
|
|
|
+ updateYearApi(params).then(
|
|
|
+ success => {
|
|
|
+ if (success.errorCode === 0) {
|
|
|
+ message.success('设置折旧年限成功。');
|
|
|
+ } else {
|
|
|
+ message.warning(success.errorMessage);
|
|
|
+ }
|
|
|
+ clearDatas();
|
|
|
+ if (isAllSearch.value) {
|
|
|
+ searchChange();
|
|
|
+ } else {
|
|
|
+ categoriesSelected();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ Common.processException(error);
|
|
|
+ },
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+// 设置折旧方法
|
|
|
+const setMethod = params => {
|
|
|
+ updateMethodApi(params).then(
|
|
|
+ success => {
|
|
|
+ if (success.errorCode === 0) {
|
|
|
+ message.success('设置折旧方法成功。');
|
|
|
+ } else {
|
|
|
+ message.warning(success.errorMessage);
|
|
|
+ }
|
|
|
+ clearDatas();
|
|
|
+ if (isAllSearch.value) {
|
|
|
+ searchChange();
|
|
|
+ } else {
|
|
|
+ categoriesSelected();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ Common.processException(error);
|
|
|
+ },
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+// 设置残值率
|
|
|
+const setReservedRate = params => {
|
|
|
+ updateReservedRateApi(params).then(
|
|
|
+ success => {
|
|
|
+ if (success.errorCode === 0) {
|
|
|
+ message.success('设置残值率成功。');
|
|
|
+ } else {
|
|
|
+ message.warning(success.errorMessage);
|
|
|
+ }
|
|
|
+ clearDatas();
|
|
|
+ if (isAllSearch.value) {
|
|
|
+ searchChange();
|
|
|
+ } else {
|
|
|
+ categoriesSelected();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ Common.processException(error);
|
|
|
+ },
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+// 设置计提折旧
|
|
|
+const setDepreciation = () => {
|
|
|
+ if (!selectedIds.value || selectedIds.value.length === 0) {
|
|
|
+ message.warning('请您至少选择一条分类数据。');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Modal.confirm({
|
|
|
+ title: '提示',
|
|
|
+ content: h('div', {}, '您确定要将所选数据设置为计提折旧吗?'),
|
|
|
+ onOk() {
|
|
|
+ updateExtractDepreciation(true);
|
|
|
+ },
|
|
|
+ });
|
|
|
+};
|
|
|
+// 设置不提折旧
|
|
|
+const cancelDepreciation = () => {
|
|
|
+ if (!selectedIds.value || selectedIds.value.length === 0) {
|
|
|
+ message.warning('请您至少选择一条分类数据。');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Modal.confirm({
|
|
|
+ title: '提示',
|
|
|
+ content: h('div', {}, '您确定要将所选数据设置为不提折旧吗?'),
|
|
|
+ onOk() {
|
|
|
+ updateExtractDepreciation(false);
|
|
|
+ },
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 根据分类ID查询折旧信息(处理刷新情况,避免点击父类资产时刷新无效)
|
|
|
+const categoriesSelected = (key, selected) => {
|
|
|
+ let nowKey;
|
|
|
+ let nowCategory;
|
|
|
+ if (selected) {
|
|
|
+ if (!selected.node.dataRef.children) {
|
|
|
+ selectCategoryId.value = nowKey = key;
|
|
|
+ selectCategory.value = nowCategory = selected;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ nowKey = [...selectCategoryId.value];
|
|
|
+ nowCategory = { ...selectCategory.value };
|
|
|
+ }
|
|
|
+ if (nowKey && nowKey.length) {
|
|
|
+ if (!nowCategory.node.dataRef.children) {
|
|
|
+ queryByIdApi(nowKey[0]).then(
|
|
|
+ success => {
|
|
|
+ if (success.name) {
|
|
|
+ dataSource.value = [{ ...success }];
|
|
|
+ }
|
|
|
+ isAllSearch.value = false;
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ Common.processException(error);
|
|
|
+ },
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+// 获取的分页参数并查询
|
|
|
+const getPageParams = (start, length) => {
|
|
|
+ current.value = start;
|
|
|
+ searchParams.range.start = (start - 1) * length;
|
|
|
+ searchParams.range.length = length;
|
|
|
+ getInfo();
|
|
|
+};
|
|
|
+
|
|
|
+// 查询回到第一页
|
|
|
+const searchChange = debounce(() => {
|
|
|
+ getPageParams(1, 20);
|
|
|
+}, 500);
|
|
|
+
|
|
|
+// 获取所选项的数据
|
|
|
+const getSelectColumn = rows => {
|
|
|
+ selectedIds.value = rows.selectedRowKeys;
|
|
|
+};
|
|
|
+
|
|
|
+// 获取资产分类
|
|
|
+const getCategories = () => {
|
|
|
+ queryCategoriesApi().then(
|
|
|
+ success => {
|
|
|
+ if (success && success.length) {
|
|
|
+ treeDatas.value = success;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ Common.processException(error);
|
|
|
+
|
|
|
+ },
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+// 根据分类名字查询信息
|
|
|
+const getInfo = () => {
|
|
|
+ isLoading.value = true;
|
|
|
+ const params = JSON.parse(JSON.stringify(searchParams));
|
|
|
+ queryByNameApi(params).then(
|
|
|
+ success => {
|
|
|
+ if (success.dataList && success.dataList.length) {
|
|
|
+ dataSource.value = success.dataList;
|
|
|
+ }
|
|
|
+ infoTotal.value = success.totalSize;
|
|
|
+ isLoading.value = false;
|
|
|
+ isAllSearch.value = true;
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ isLoading.value = false;
|
|
|
+ Common.processException(error);
|
|
|
+ },
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+// 查询所有资产折旧方法
|
|
|
+const getMethods = () => {
|
|
|
+ getMethodsApi().then(
|
|
|
+ success => {
|
|
|
+ if (success.errorCode === 0) {
|
|
|
+ if (success.datas && success.datas.length) {
|
|
|
+ depreciationMethods.value = success.datas;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ message.warning(success.errorMessage);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ Common.processException(error);
|
|
|
+ },
|
|
|
+ );
|
|
|
+};
|
|
|
+// 设置计提折旧或不提折旧
|
|
|
+const updateExtractDepreciation = flag => {
|
|
|
+ const params = {
|
|
|
+ isExtractDepreciation: flag,
|
|
|
+ assetCategoryIds: selectedIds.value,
|
|
|
+ };
|
|
|
+ updateExtractApi(params).then(
|
|
|
+ success => {
|
|
|
+ if (success.errorCode === 0) {
|
|
|
+ if (flag) {
|
|
|
+ message.success('设置计提折旧成功。');
|
|
|
+ } else {
|
|
|
+ message.success('设置不提折旧成功。');
|
|
|
+ }
|
|
|
+ clearDatas();
|
|
|
+ if (isAllSearch.value) {
|
|
|
+ searchChange();
|
|
|
+ } else {
|
|
|
+ categoriesSelected();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ message.warning(success.errorMessage);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ Common.processException(error);
|
|
|
+ },
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+getInfo();
|
|
|
+getMethods();
|
|
|
+getCategories();
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.tree_box {
|
|
|
+ height: 86vh;
|
|
|
+ overflow: auto;
|
|
|
+ border: 1px solid #dddddd;
|
|
|
+ margin-right: 4px;
|
|
|
+ border-bottom: none;
|
|
|
+}
|
|
|
+
|
|
|
+.table_box {
|
|
|
+ padding: 6px;
|
|
|
+ border: 1px solid #dddddd;
|
|
|
+ border-bottom: none;
|
|
|
+}
|
|
|
+
|
|
|
+.operation_box {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.ant-btn>span {
|
|
|
+ color: #267fcf;
|
|
|
+}
|
|
|
+
|
|
|
+.footer_box {
|
|
|
+ background-color: #fafafa;
|
|
|
+}
|
|
|
+p{
|
|
|
+ margin: 0 !important;
|
|
|
+ padding: 0 !important;
|
|
|
+}
|
|
|
+</style>
|