ZN
6 天以前 7ff67bff3b4ac5e503ca4291f03eee1ac213fd33
refactor(financial): 简化收支借款管理页面并移除编辑功能

- 移除收入、支出、借款管理的编辑页面及相关路由
- 简化列表页搜索条件,将日期范围筛选改为客户名称搜索
- 移除列表页的编辑、删除、新增等操作按钮
- 修复API删除接口URL缺少前导斜杠的问题
- 清理未使用的代码和组件,优化页面结构
已修改6个文件
已删除3个文件
584 ■■■■■ 文件已修改
src/api/financialManagement/expenseManagement.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/financialManagement/revenueManagement.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/financialManagement/expenseManagement/edit.vue 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/financialManagement/expenseManagement/index.vue 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/financialManagement/loanManagement/edit.vue 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/financialManagement/loanManagement/index.vue 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/financialManagement/revenueManagement/edit.vue 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/financialManagement/revenueManagement/index.vue 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/financialManagement/expenseManagement.js
@@ -26,7 +26,7 @@
export const delAccountExpense = (data) => {
  return request({
    url: "account/accountExpense/del",
    url: "/account/accountExpense/del",
    method: "delete",
    data,
  });
src/api/financialManagement/revenueManagement.js
@@ -26,7 +26,7 @@
export const delAccountIncome = (data) => {
  return request({
    url: "account/accountIncome/del",
    url: "/account/accountIncome/del",
    method: "delete",
    data,
  });
src/pages.json
@@ -26,13 +26,6 @@
      }
    },
    {
      "path": "pages/financialManagement/revenueManagement/edit",
      "style": {
        "navigationBarTitleText": "收入编辑",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/financialManagement/expenseManagement/index",
      "style": {
        "navigationBarTitleText": "支出管理",
@@ -40,23 +33,9 @@
      }
    },
    {
      "path": "pages/financialManagement/expenseManagement/edit",
      "style": {
        "navigationBarTitleText": "支出编辑",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/financialManagement/loanManagement/index",
      "style": {
        "navigationBarTitleText": "借款管理",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/financialManagement/loanManagement/edit",
      "style": {
        "navigationBarTitleText": "借款编辑",
        "navigationStyle": "custom"
      }
    },
src/pages/financialManagement/expenseManagement/edit.vue
ÎļþÒÑɾ³ý
src/pages/financialManagement/expenseManagement/index.vue
@@ -4,17 +4,11 @@
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <uni-datetime-picker type="daterange" v-model="filters.entryDate" @change="onDateChange" />
          <up-input class="search-text" placeholder="请输入客户名称搜索" v-model="searchForm.supplierName" clearable />
        </view>
        <view class="search-input">
          <up-input readonly placeholder="付款方式" v-model="expenseMethodLabel" @click="methodPickerShow = true" />
        <view class="filter-button" @click="handleQuery">
          <up-icon name="search" size="24" color="#999"></up-icon>
        </view>
        <view class="filter-button" @click="getList">
          <up-icon name="search" size="24" color="#999" />
        </view>
      </view>
    <view class="actions">
        <u-button type="primary" size="small" @click="goAdd">新增</u-button>
      </view>
    </view>
    <view class="ledger-list" v-if="list.length>0">
@@ -36,31 +30,24 @@
          <view class="detail-row"><text class="detail-label">发票号码</text><text class="detail-value">{{ item.invoiceNumber || '--' }}</text></view>
          <view class="detail-row"><text class="detail-label">备注</text><text class="detail-value">{{ item.note || '--' }}</text></view>
        </view>
        <view class="card-actions">
          <u-button size="small" @click="goEdit(item)" :disabled="!!item.businessId">编辑</u-button>
          <u-button size="small" type="error" @click="confirmDelete(item)" :disabled="!!item.businessId">删除</u-button>
        </view>
      </view>
    </view>
    <view class="no-data" v-else><text>暂无数据</text></view>
    <up-action-sheet :show="methodPickerShow" :actions="checkoutPayment" title="付款方式" @select="onSelectMethod" @close="methodPickerShow=false" />
  </view>
  </template>
<script setup>
import { ref, reactive } from "vue";
import { onShow } from "@dcloudio/uni-app";
import { listPage, delAccountExpense } from "@/api/financialManagement/expenseManagement";
import { listPage } from "@/api/financialManagement/expenseManagement";
import { useDict } from "@/utils/dict";
const list = ref([]);
const filters = reactive({ entryDate: null, expenseMethod: undefined, entryDateStart: undefined, entryDateEnd: undefined });
const { checkout_payment, expense_types } = useDict("checkout_payment", "expense_types");
const checkoutPayment = ref([]);
const expenseTypes = ref([]);
const methodPickerShow = ref(false);
const expenseMethodLabel = ref("");
const searchForm = reactive({ supplierName: null,current:-1,size:-1 });
const syncDict = () => {
  checkoutPayment.value = (checkout_payment?.value || []).map(i => ({ label: i.label, value: i.value }));
@@ -68,28 +55,13 @@
};
const getList = () => {
  listPage({ expenseMethod: filters.expenseMethod, entryDateStart: filters.entryDateStart, entryDateEnd: filters.entryDateEnd, current: 1, size: 100 })
  listPage({...searchForm })
    .then(res => {
      const records = res?.data?.records ?? res?.records ?? [];
      list.value = records;
    });
};
const onDateChange = (val) => {
  if (val && val.length === 2) {
    filters.entryDateStart = val[0];
    filters.entryDateEnd = val[1];
  } else {
    filters.entryDateStart = undefined;
    filters.entryDateEnd = undefined;
  }
};
const onSelectMethod = (e) => {
  filters.expenseMethod = e.value;
  expenseMethodLabel.value = e.label;
  methodPickerShow.value = false;
};
const methodText = (v) => {
  const m = checkoutPayment.value.find(i=>String(i.value)===String(v));
@@ -104,34 +76,10 @@
  return n.toFixed(2);
};
const goAdd = () => {
  uni.navigateTo({ url: "/pages/financialManagement/expenseManagement/edit?type=add" });
};
const goEdit = (row) => {
  uni.navigateTo({ url: `/pages/financialManagement/expenseManagement/edit?type=edit&id=${row.id}` });
};
const confirmDelete = (row) => {
  uni.showModal({
    title: "提示",
    content: "确认删除该记录?",
    success: async (r) => {
      if (r.confirm) {
        const ids = Array.isArray(row) ? row.map(i=>i.id) : [row.id];
        const res = await delAccountExpense(ids);
        if (res?.code === 200) getList();
      }
    },
  });
const handleQuery = () => {
  getList();
};
const onExpenseTypeConfirm = (e) => {
  const item = expenseTypes.value[e.value[0]];
  if (item) form.expenseType = item.value;
};
const onMethodConfirm = (e) => {
  const item = checkoutPayment.value[e.value[0]];
  if (item) form.expenseMethod = item.value;
};
const goBack = () => {
  uni.navigateBack();
src/pages/financialManagement/loanManagement/edit.vue
ÎļþÒÑɾ³ý
src/pages/financialManagement/loanManagement/index.vue
@@ -4,22 +4,11 @@
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <up-input v-model="filters.borrowerName" placeholder="借款人姓名" clearable />
          <up-input class="search-text" placeholder="请输入客户名称搜索" v-model="searchForm.borrowerName" clearable />
        </view>
        <view class="search-input">
          <uni-datetime-picker type="daterange" v-model="filters.borrowDate" @change="onDateChange" />
        <view class="filter-button" @click="handleQuery">
          <up-icon name="search" size="24" color="#999"></up-icon>
        </view>
        <view class="search-input">
          <up-picker :columns="[statusOptions]" key-name="label" v-model="statusIndex" @confirm="onStatusConfirm">
            <up-input readonly :value="statusLabel" placeholder="借款状态" />
          </up-picker>
        </view>
        <view class="filter-button" @click="getList">
          <up-icon name="search" size="24" color="#999" />
        </view>
      </view>
    <view class="actions">
        <u-button type="primary" size="small" @click="goAdd">新增</u-button>
      </view>
    </view>
    <view class="ledger-list" v-if="list.length>0">
@@ -41,103 +30,33 @@
          <view class="detail-row"><text class="detail-label">实际还款日期</text><text class="detail-value">{{ item.repayDate || '--' }}</text></view>
          <view class="detail-row"><text class="detail-label">备注</text><text class="detail-value">{{ item.remark || '--' }}</text></view>
        </view>
        <view class="card-actions">
          <u-button size="small" @click="goEdit(item)">编辑</u-button>
          <u-button size="small" type="warning" @click="goRepay(item)" :disabled="item.status!==1">还款</u-button>
          <u-button size="small" type="error" @click="confirmDelete(item)">删除</u-button>
        </view>
      </view>
    </view>
    <view class="no-data" v-else><text>暂无数据</text></view>
    <up-popup :show="formShow" mode="bottom" @close="closeForm">
      <view class="popup">
        <view class="popup-header">{{ formMode==='add'?'新增借款': formMode==='repay'?'还款':'编辑借款' }}</view>
        <up-form :model="form" :rules="rules" ref="formRef">
          <up-form-item label="借款人姓名" prop="borrowerName">
            <up-input v-model="form.borrowerName" placeholder="请输入" />
          </up-form-item>
          <up-form-item label="借款金额" prop="borrowAmount">
            <up-input type="number" v-model="form.borrowAmount" placeholder="请输入" />
          </up-form-item>
          <up-form-item label="借款利率(%)" prop="interestRate">
            <up-input type="number" v-model="form.interestRate" placeholder="例如 5.85" />
          </up-form-item>
          <up-form-item label="借款日期" prop="borrowDate">
            <uni-datetime-picker type="date" v-model="form.borrowDate" />
          </up-form-item>
          <up-form-item v-if="formMode==='repay'" label="实际还款日期" prop="repayDate">
            <uni-datetime-picker type="date" v-model="form.repayDate" />
          </up-form-item>
          <up-form-item label="备注" prop="remark">
            <up-textarea v-model="form.remark" autoHeight />
          </up-form-item>
        </up-form>
        <view class="popup-actions">
          <u-button @click="closeForm">取消</u-button>
          <u-button type="primary" @click="submitForm">保存</u-button>
        </view>
      </view>
    </up-popup>
  </view>
</template>
<script setup>
import { ref, reactive } from "vue";
import { onShow } from "@dcloudio/uni-app";
import { listPage, delAccountLoan } from "@/api/financialManagement/loanManagement";
import { listPage } from "@/api/financialManagement/loanManagement";
const list = ref([]);
const filters = reactive({ borrowerName: "", borrowDate: null, entryDateStart: undefined, entryDateEnd: undefined, status: undefined });
const statusOptions = ref([{ label: "全部", value: undefined }, { label: "待还款", value: 1 }, { label: "已还款", value: 2 }]);
const statusIndex = ref([0]);
const statusLabel = ref("");
const searchForm = reactive({ borrowerName: "", current: -1, size: -1 });
const formShow = ref(false);
const formMode = ref("add");
const formRef = ref();
const form = reactive({
  id: undefined,
  borrowerName: "",
  borrowAmount: undefined,
  interestRate: undefined,
  borrowDate: undefined,
  repayDate: undefined,
  remark: "",
  status: undefined,
});
const rules = {
  borrowerName: [{ required: true, message: "请输入", trigger: "blur" }],
  borrowAmount: [{ required: true, message: "请输入", trigger: "blur" }],
  interestRate: [{ required: true, message: "请输入", trigger: "blur" }],
  borrowDate: [{ required: true, message: "请选择", trigger: "change" }],
  repayDate: [{ validator: (_r, v, cb)=>{ if (formMode.value==='repay' && !v) return cb(new Error('请选择')); cb(); }, trigger: "change" }],
};
const getList = () => {
  const extra = {};
  if (filters.entryDateStart && filters.entryDateEnd) {
    extra.entryDateStart = filters.entryDateStart;
    extra.entryDateEnd = filters.entryDateEnd;
  }
  if (filters.status) extra.status = filters.status;
  listPage({ borrowerName: filters.borrowerName, ...extra, current: 1, size: 100 })
  listPage({ ...searchForm, current: -1, size: -1 })
    .then(res => {
      const records = res?.data?.records ?? res?.records ?? [];
      list.value = records;
    });
};
const onDateChange = (val) => {
  if (val && val.length === 2) {
    filters.entryDateStart = val[0];
    filters.entryDateEnd = val[1];
  } else {
    filters.entryDateStart = undefined;
    filters.entryDateEnd = undefined;
  }
const handleQuery = () => {
  searchForm.current = 1;
  getList();
};
const statusText = (s) => s===1?'待还款': s===2?'已还款':'';
const statusType = (s) => s===1?'error': s===2?'success':'primary';
const fmtAmount = (v) => {
@@ -148,37 +67,6 @@
  if (v===undefined || v===null || v==='') return '-';
  const n = parseFloat(v);
  return n.toFixed(2) + '%';
};
const goAdd = () => {
  uni.navigateTo({ url: "/pages/financialManagement/loanManagement/edit?type=add" });
};
const goEdit = (row) => {
  uni.navigateTo({ url: `/pages/financialManagement/loanManagement/edit?type=edit&id=${row.id}` });
};
const goRepay = (row) => {
  uni.navigateTo({ url: `/pages/financialManagement/loanManagement/edit?type=repay&id=${row.id}` });
};
const confirmDelete = (row) => {
  uni.showModal({
    title: "提示",
    content: "确认删除该记录?",
    success: async (r) => {
      if (r.confirm) {
        const ids = Array.isArray(row) ? row.map(i=>i.id) : [row.id];
        const res = await delAccountLoan(ids);
        if (res?.code === 200) getList();
      }
    },
  });
};
const onStatusConfirm = (e) => {
  const item = statusOptions.value[e.value[0]];
  if (item) {
    filters.status = item.value;
    statusLabel.value = item.label || "";
  }
};
const goBack = () => {
src/pages/financialManagement/revenueManagement/edit.vue
ÎļþÒÑɾ³ý
src/pages/financialManagement/revenueManagement/index.vue
@@ -4,18 +4,12 @@
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <uni-datetime-picker type="daterange" v-model="filters.entryDate" @change="onDateChange" />
          <up-input class="search-text" placeholder="请输入客户名称搜索" v-model="searchForm.customerName" clearable />
        </view>
        <view class="search-input">
          <up-input readonly placeholder="收款方式" v-model="incomeMethodLabel" @click="methodPickerShow = true" />
        </view>
        <view class="filter-button" @click="getList">
          <up-icon name="search" size="24" color="#999" />
        <view class="filter-button" @click="handleQuery">
          <up-icon name="search" size="24" color="#999"></up-icon>
        </view>
      </view>
    <view class="actions">
        <u-button type="primary" size="small" @click="goAdd">新增</u-button>
    </view>
    </view>
    <view class="ledger-list" v-if="list.length>0">
      <view class="ledger-item" v-for="item in list" :key="item.id">
@@ -31,14 +25,10 @@
        <up-divider></up-divider>
        <view class="item-details">
          <view class="detail-row"><text class="detail-label">收入日期</text><text class="detail-value">{{ item.incomeDate || '--' }}</text></view>
          <view class="detail-row"><text class="detail-label">收入类型</text><text class="detail-value">{{ incomeTypeText(item.incomeType) || '--' }}</text></view>
          <view class="detail-row"><text class="detail-label">收入类型</text><text class="detail-value">{{ incomeTypeText(item.incomeMethod) || '其他收入' }}</text></view>
          <view class="detail-row"><text class="detail-label">收入金额(元)</text><text class="detail-value highlight">{{ fmtAmount(item.incomeMoney) }}</text></view>
          <view class="detail-row"><text class="detail-label">发票号码</text><text class="detail-value">{{ item.invoiceNumber || '--' }}</text></view>
          <view class="detail-row"><text class="detail-label">备注</text><text class="detail-value">{{ item.note || '--' }}</text></view>
        </view>
        <view class="card-actions">
          <u-button size="small" @click="goEdit(item)" :disabled="!!item.businessId">编辑</u-button>
          <u-button size="small" type="error" @click="confirmDelete(item)" :disabled="!!item.businessId">删除</u-button>
        </view>
      </view>
    </view>
@@ -61,28 +51,24 @@
const incomeTypes = ref([]);
const methodPickerShow = ref(false);
const incomeMethodLabel = ref("");
const searchForm = reactive({ customerName: null,current:1,size:100 });
const syncDict = () => {
  paymentMethods.value = (payment_methods?.value || []).map(i => ({ label: i.label, value: i.value }));
  incomeTypes.value = (income_types?.value || []).filter(i=>i.value!=3).map(i => ({ label: i.label, value: i.value }));
  incomeTypes.value = (income_types?.value || []).map(i => ({ label: i.label, value: i.value }));
};
const getList = () => {
  listPage({ incomeMethod: filters.incomeMethod, entryDateStart: filters.entryDateStart, entryDateEnd: filters.entryDateEnd, current: 1, size: 100 })
  listPage({ ...searchForm })
    .then(res => {
      const records = res?.data?.records ?? res?.records ?? [];
      list.value = records;
    });
};
const onDateChange = (val) => {
  if (val && val.length === 2) {
    filters.entryDateStart = val[0];
    filters.entryDateEnd = val[1];
  } else {
    filters.entryDateStart = undefined;
    filters.entryDateEnd = undefined;
  }
const handleQuery = () => {
  searchForm.current = 1;
  getList();
};
const onSelectMethod = (e) => {