进销存升级app:
1.开票登记、开票台账、回款流水还有客户合同号字段(需要去掉)
2.采购台账、销售台账页面都需要加上删除按钮
| | |
| | | const temFutureTickets = ref(0); |
| | | const originalTicketsNum = ref(0); // 保存原始来票数 |
| | | |
| | | // 表单校验规则 |
| | | // 表单校验规则 - 使用简单的 required 规则 |
| | | const rules = { |
| | | ticketsNum: [{ required: true, message: "请输入来票数", trigger: "blur" }], |
| | | ticketsAmount: [ |
| | |
| | | |
| | | // 表单提交 |
| | | const onSubmit = async () => { |
| | | if (!formRef.value) { |
| | | console.log("表单引用不存在"); |
| | | // 在验证前,确保必填字段有值 |
| | | if (!form.value.ticketsNum || form.value.ticketsNum === "" || form.value.ticketsNum === null || form.value.ticketsNum === undefined) { |
| | | uni.showToast({ |
| | | title: "请输入来票数", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 先调用 validate 方法 |
| | | const validateResult = formRef.value.validate(); |
| | | |
| | | // 如果 validate 返回 undefined 或 null,直接提交 |
| | | if (validateResult === undefined || validateResult === null) { |
| | | submitForm(); |
| | | return; |
| | | } |
| | | |
| | | // 如果返回 Promise,使用 await 和 catch |
| | | if (validateResult && typeof validateResult.then === 'function') { |
| | | const valid = await validateResult.catch(() => false); |
| | | if (valid) { |
| | | // 表单验证通过,提交表单 |
| | | submitForm(); |
| | | } else { |
| | | // 表单验证失败 |
| | | console.log("表单验证失败"); |
| | | } |
| | | } else { |
| | | // 如果返回布尔值,直接判断 |
| | | if (validateResult) { |
| | | submitForm(); |
| | | } else { |
| | | console.log("表单验证失败"); |
| | | } |
| | | } |
| | | } catch (error) { |
| | | // 如果 validate 方法不存在或抛出错误,直接提交 |
| | | console.log("表单验证失败", error); |
| | | submitForm(); |
| | | if (!form.value.ticketsAmount || form.value.ticketsAmount === "" || form.value.ticketsAmount === null || form.value.ticketsAmount === undefined) { |
| | | uni.showToast({ |
| | | title: "请输入本次来票金额", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 确保字段是数字类型,并转换为字符串(因为表单可能需要字符串类型) |
| | | const ticketsNum = Number(form.value.ticketsNum); |
| | | const ticketsAmount = Number(form.value.ticketsAmount); |
| | | |
| | | // 如果来票数为0或来票金额为0,提示用户 |
| | | if (isNaN(ticketsNum) || ticketsNum <= 0) { |
| | | uni.showToast({ |
| | | title: "来票数必须大于0", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | if (isNaN(ticketsAmount) || ticketsAmount <= 0) { |
| | | uni.showToast({ |
| | | title: "本次来票金额必须大于0", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 更新表单值,确保是有效的数字字符串 |
| | | form.value.ticketsNum = ticketsNum.toString(); |
| | | form.value.ticketsAmount = ticketsAmount.toString(); |
| | | |
| | | // 手动验证通过后,直接提交,跳过表单验证(避免真机上的验证问题) |
| | | submitForm(); |
| | | }; |
| | | const purchaseLedgerId = ref(""); |
| | | const productModelId = ref({}); |
| | |
| | | <text class="detail-value">{{ item.entryDate }}</text> |
| | | </view> |
| | | </view> |
| | | <!-- 仅非“审批通过”的台账展示删除按钮 --> |
| | | <view |
| | | class="detail-row" |
| | | v-if="item.approvalStatus !== 3" |
| | | style="justify-content: flex-end; margin-top: 8px;" |
| | | > |
| | | <up-button |
| | | type="error" |
| | | size="small" |
| | | plain |
| | | @click.stop="handleDelete(item)" |
| | | > |
| | | 删除 |
| | | </up-button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import { purchaseListPage } from "@/api/procurementManagement/procurementLedger"; |
| | | import { purchaseListPage, delPurchase } from "@/api/procurementManagement/procurementLedger"; |
| | | const userStore = useUserStore(); |
| | | const approvalStatusText = { |
| | | 1: "待审核", |
| | |
| | | } |
| | | }; |
| | | |
| | | // 删除单条采购台账 |
| | | const handleDelete = row => { |
| | | if (!row || !row.id) { |
| | | uni.showToast({ |
| | | title: "数据有误,无法删除", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | uni.showModal({ |
| | | title: "提示", |
| | | content: "选中的内容将被删除,是否确认删除?", |
| | | confirmText: "确认", |
| | | cancelText: "取消", |
| | | success: res => { |
| | | if (res.confirm) { |
| | | delPurchase([row.id]) |
| | | .then(result => { |
| | | // 成功:code === 200 |
| | | if (result && result.code === 200) { |
| | | uni.showToast({ |
| | | title: "删除成功", |
| | | icon: "success", |
| | | }); |
| | | getList(); |
| | | return; |
| | | } |
| | | // 业务失败:优先展示后端返回的 msg(如 CG2026... 不允许删除) |
| | | uni.showToast({ |
| | | title: (result && result.msg) || "删除失败", |
| | | icon: "none", |
| | | }); |
| | | }) |
| | | .catch(error => { |
| | | // 对于 request 封装返回的 '500' 或其他 code,错误提示已经在 request 里 toast 过了,这里不再重复覆盖 |
| | | if (error === "500" || typeof error === "number") { |
| | | return; |
| | | } |
| | | // 只有在真正异常时,才在这里兜底提示 |
| | | const msg = |
| | | (error && error.msg) || |
| | | (error && error.response && error.response.data && error.response.data.msg) || |
| | | (error && error.message) || |
| | | "删除失败"; |
| | | uni.showToast({ |
| | | title: msg, |
| | | icon: "none", |
| | | }); |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | onShow(() => { |
| | | // 页面显示时刷新列表 |
| | | getList(); |
| | |
| | | <view class="search-bar"> |
| | | <view class="search-input"> |
| | | <up-input class="search-text" |
| | | placeholder="请输入客户名称/合同号搜索" |
| | | placeholder="请输入客户名称/销售合同号搜索" |
| | | v-model="searchForm.searchText" |
| | | @change="handleQuery" |
| | | clearable /> |
| | |
| | | <view class="detail-row"> |
| | | <text class="detail-label">客户名称</text> |
| | | <text class="detail-value">{{ item.customerName }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">客户合同号</text> |
| | | <text class="detail-value">{{ item.customerContractNo }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">项目</text> |
| | |
| | | <text class="detail-value">{{ item.customerName }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">客户合同号</text> |
| | | <text class="detail-value">{{ item.customerContractNo }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">业务员</text> |
| | | <text class="detail-value">{{ item.salesman }}</text> |
| | | </view> |
| | |
| | | <text class="info-value">{{ form.salesContractNo }}</text> |
| | | </view> |
| | | <view class="info-item"> |
| | | <text class="info-label">客户合同号</text> |
| | | <text class="info-value highlight">{{ form.customerContractNo }}</text> |
| | | </view> |
| | | <view class="info-item"> |
| | | <text class="info-label">客户名称</text> |
| | | <text class="info-value">{{ form.customerName }}</text> |
| | | </view> |
| | |
| | | const form = ref({ |
| | | id: '', |
| | | salesContractNo: '', |
| | | customerContractNo: '', |
| | | customerId: '', |
| | | customerName: '', |
| | | projectName: '', |
| | |
| | | const searchForm = ref({ |
| | | customerName: "", |
| | | status: true, |
| | | customerContractNo: "", |
| | | projectName: "", |
| | | }); |
| | | // 获取标签样式类 |
| | |
| | | <up-divider></up-divider> |
| | | <view class="item-details"> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">客户合同号</text> |
| | | <text class="detail-value">{{ item.customerContractNo }}</text> |
| | | </view> |
| | | <view class="detail-row"> |
| | | <text class="detail-label">客户名称</text> |
| | | <text class="detail-value">{{ item.customerName }}</text> |
| | | </view> |
| | |
| | | </view> |
| | | </view> |
| | | <up-divider></up-divider> |
| | | <u-button class="detail-button" |
| | | <view class="detail-buttons"> |
| | | <u-button class="detail-button" |
| | | size="small" |
| | | type="primary" |
| | | @click="openOut(item)"> |
| | | 发货状态 |
| | | </u-button> |
| | | <u-button class="detail-button" |
| | | size="small" |
| | | type="error" |
| | | plain |
| | | @click.stop="handleDelete(item)"> |
| | | 删除 |
| | | </u-button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | <script setup> |
| | | import { ref } from "vue"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import { ledgerListPage } from "@/api/salesManagement/salesLedger"; |
| | | import { |
| | | ledgerListPage, |
| | | delLedger, |
| | | productList, |
| | | } from "@/api/salesManagement/salesLedger"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | const userStore = useUserStore(); |
| | |
| | | |
| | | // 销售台账数据 |
| | | const ledgerList = ref([]); |
| | | |
| | | // 判断是否存在已发货/发货完成的产品 |
| | | const hasShippedProducts = products => { |
| | | if (!products || products.length === 0) return false; |
| | | return products.some(p => { |
| | | const statusStr = (p.shippingStatus ?? "").toString(); |
| | | // 包含“发货”或有发货日期/车牌号视为已发货 |
| | | return ( |
| | | statusStr.includes("发货") || |
| | | !!p.shippingDate || |
| | | !!p.shippingCarNumber |
| | | ); |
| | | }); |
| | | }; |
| | | |
| | | // 返回上一页 |
| | | const goBack = () => { |
| | |
| | | uni.setStorageSync("outData", JSON.stringify(item)); |
| | | uni.navigateTo({ |
| | | url: "/pages/sales/salesAccount/out", |
| | | }); |
| | | }; |
| | | |
| | | // 删除单条销售台账 |
| | | const handleDelete = async row => { |
| | | if (!row || !row.id) return; |
| | | |
| | | // 获取产品列表,用于判断是否已发货 |
| | | let products = row.children && row.children.length > 0 ? row.children : null; |
| | | if (!products) { |
| | | try { |
| | | const res = await productList({ salesLedgerId: row.id, type: 1 }); |
| | | products = res.data || res.records || []; |
| | | } catch (e) { |
| | | products = []; |
| | | } |
| | | } |
| | | |
| | | if (hasShippedProducts(products)) { |
| | | uni.showToast({ |
| | | title: "已发货/发货完成的销售订单不能删除", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | uni.showModal({ |
| | | title: "删除确认", |
| | | content: "选中的内容将被删除,是否确认删除?", |
| | | success: async res => { |
| | | if (res.confirm) { |
| | | try { |
| | | showLoadingToast("处理中..."); |
| | | await delLedger([row.id]); |
| | | closeToast(); |
| | | uni.showToast({ |
| | | title: "删除成功", |
| | | icon: "success", |
| | | }); |
| | | getList(); |
| | | } catch (e) { |
| | | closeToast(); |
| | | uni.showToast({ |
| | | title: "删除失败,请重试", |
| | | icon: "none", |
| | | }); |
| | | } |
| | | } |
| | | }, |
| | | }); |
| | | }; |
| | | // 处理台账信息操作(查看/编辑/新增) |
| | |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/styles/sales-common.scss"; |
| | | .detail-buttons { |
| | | display: flex; |
| | | gap: 10px; |
| | | justify-content: space-between; |
| | | } |
| | | </style> |