升级pro
1.财务页面删除掉一些功能
2.财务管理应付管理、应收管理逻辑修改
3.生成凭证页面重构
4.整体样式修改
| | |
| | | }
|
| | | }
|
| | | .table_list {
|
| | | margin-top: 20px;
|
| | | background: rgba(255, 255, 255, 0.88);
|
| | | border: 1px solid var(--surface-border);
|
| | | border-radius: var(--radius-md);
|
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form" style="margin-bottom: 20px;"> |
| | | <div> |
| | | <span class="search_title">客户名称:</span> |
| | | <el-input v-model="searchForm.customerName" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form" style="margin-bottom: 20px;"> |
| | | <div> |
| | | <span class="search_title">客户名称:</span> |
| | | <el-input v-model="searchForm.customerName" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <div class="search_form"> |
| | | <div style="margin-bottom: 10px;"> |
| | | <span class="search_title">供应商档案:</span> |
| | | <el-input |
| | | v-model="searchForm.supplierName" |
| | |
| | | >搜索</el-button |
| | | > |
| | | </div> |
| | | <div> |
| | | <div style="margin-bottom: 10px;"> |
| | | <el-button type="primary" @click="openForm('add')" |
| | | >新增供应商</el-button |
| | | > |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form" style="margin-bottom: 20px;"> |
| | | <div> |
| | | <span class="search_title">知识标题:</span> |
| | | <el-input |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search-wrapper"> |
| | | <div class="search-wrapper mb20"> |
| | | <el-form |
| | | :model="searchForm" |
| | | class="demo-form-inline" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">临期日期:</span> |
| | | <el-date-picker |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">检定日期:</span> |
| | | <el-date-picker |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">录入日期:</span> |
| | | <el-date-picker |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "固定资产", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "无形资产", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="600px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="600px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> |
| | | <el-form-item label="科目编码" prop="subjectCode"> |
| | | <el-input v-model="form.subjectCode" placeholder="请输入科目编码" /> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "总帐科目", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "进项发票", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "付款单", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "付款申请", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "采购入库", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog title="对账明细" v-model="detailDialogVisible" width="900px" append-to-body> |
| | | <FormDialog title="对账明细" v-model="detailDialogVisible" width="900px" @confirm="printDetail" @cancel="detailDialogVisible = false" operationType="detail"> |
| | | <div class="statement-header"> |
| | | <h3>{{ currentSupplier }} 应付对账单</h3> |
| | | <p>对账期间: {{ currentPeriod }}</p> |
| | |
| | | <el-table-column prop="remark" label="备注" show-overflow-tooltip /> |
| | | </el-table> |
| | | <template #footer> |
| | | <el-button @click="detailDialogVisible = false">关闭</el-button> |
| | | <el-button type="primary" @click="printDetail">打印</el-button> |
| | | <el-button @click="detailDialogVisible = false">关闭</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | |
| | | <FormDialog title="生成对账单" v-model="generateDialogVisible" width="1000px" @confirm="confirmGenerate" @cancel="generateDialogVisible = false"> |
| | | <el-form :model="generateForm" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="选择供应商" prop="supplierId"> |
| | | <el-select v-model="generateForm.supplierId" placeholder="请选择供应商" style="width: 100%;" @change="onSupplierChange"> |
| | | <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="对账月份" prop="period"> |
| | | <el-date-picker v-model="generateForm.period" type="month" placeholder="选择月份" value-format="YYYY-MM" style="width: 100%;" @change="onPeriodChange" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <div v-if="purchaseData.length > 0" class="purchase-section"> |
| | | <div class="section-title">本月采购数据</div> |
| | | <el-table :data="purchaseData" border style="width: 100%; margin-bottom: 15px;" v-loading="purchaseLoading" @selection-change="handlePurchaseSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column prop="date" label="日期" width="120" /> |
| | | <el-table-column prop="code" label="单据编号" width="150" /> |
| | | <el-table-column prop="type" label="类型" width="100"> |
| | | <template #default="{ row }"> |
| | | <el-tag :type="row.type === '入库' ? 'success' : 'danger'">{{ row.type }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="amount" label="金额" width="120"> |
| | | <template #default="{ row }"> |
| | | <span :class="row.type === '入库' ? 'text-danger' : 'text-success'">¥{{ formatMoney(row.amount) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="remark" label="备注" /> |
| | | </el-table> |
| | | |
| | | <div class="summary-row"> |
| | | <span>期初余额: <strong class="text-primary">¥{{ formatMoney(generateForm.beginBalance) }}</strong></span> |
| | | <span>本期应付: <strong class="text-danger">¥{{ formatMoney(generateForm.currentPayable) }}</strong></span> |
| | | <span>本期付款: <strong class="text-success">¥{{ formatMoney(generateForm.currentPayment) }}</strong></span> |
| | | <span>期末余额: <strong class="text-primary">¥{{ formatMoney(calculateEndBalance(generateForm.beginBalance, generateForm.currentPayable, generateForm.currentPayment)) }}</strong></span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-else-if="generateForm.supplierId && !purchaseLoading" class="empty-tip"> |
| | | <el-empty description="该供应商本月暂无采购数据" /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <el-button type="primary" @click="confirmGenerate" :disabled="!canGenerate">确认生成</el-button> |
| | | <el-button @click="generateDialogVisible = false">取消</el-button> |
| | | </template> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "应付对账", |
| | |
| | | const currentPeriod = ref(""); |
| | | const detailData = ref([]); |
| | | |
| | | const generateDialogVisible = ref(false); |
| | | const purchaseLoading = ref(false); |
| | | const purchaseData = ref([]); |
| | | const selectedPurchases = ref([]); |
| | | |
| | | const generateForm = reactive({ |
| | | supplierId: "", |
| | | supplierName: "", |
| | | period: "", |
| | | beginBalance: 0, |
| | | currentPayable: 0, |
| | | currentPayment: 0, |
| | | }); |
| | | |
| | | const canGenerate = computed(() => { |
| | | return generateForm.supplierId && generateForm.period && selectedPurchases.value.length > 0; |
| | | }); |
| | | |
| | | const supplierList = [ |
| | | { id: 1, name: "北京原材料供应商" }, |
| | | { id: 2, name: "上海电子元器件公司" }, |
| | |
| | | { id: 2, statementCode: "DZ202401002", supplierId: 2, supplierName: "上海电子元器件公司", period: "2024-01", beginBalance: 10000, currentPayable: 20000, currentPayment: 15000, endBalance: 15000 }, |
| | | { id: 3, statementCode: "DZ202402001", supplierId: 1, supplierName: "北京原材料供应商", period: "2024-02", beginBalance: 25000, currentPayable: 18000, currentPayment: 20000, endBalance: 23000 }, |
| | | ]; |
| | | |
| | | const calculateEndBalance = (beginBalance, currentPayable, currentPayment) => { |
| | | return beginBalance + currentPayable - currentPayment; |
| | | }; |
| | | |
| | | const formatMoney = (value) => { |
| | | if (value === undefined || value === null) return "0.00"; |
| | |
| | | }; |
| | | |
| | | const generateStatement = () => { |
| | | ElMessage.success("对账单生成成功"); |
| | | generateForm.supplierId = ""; |
| | | generateForm.supplierName = ""; |
| | | generateForm.period = ""; |
| | | generateForm.beginBalance = 0; |
| | | generateForm.currentPayable = 0; |
| | | generateForm.currentPayment = 0; |
| | | purchaseData.value = []; |
| | | selectedPurchases.value = []; |
| | | generateDialogVisible.value = true; |
| | | }; |
| | | |
| | | const onSupplierChange = (supplierId) => { |
| | | const supplier = supplierList.find(item => item.id === supplierId); |
| | | if (supplier) { |
| | | generateForm.supplierName = supplier.name; |
| | | } |
| | | loadPurchaseData(); |
| | | }; |
| | | |
| | | const onPeriodChange = () => { |
| | | loadPurchaseData(); |
| | | }; |
| | | |
| | | const loadPurchaseData = () => { |
| | | if (!generateForm.supplierId || !generateForm.period) { |
| | | purchaseData.value = []; |
| | | return; |
| | | } |
| | | |
| | | purchaseLoading.value = true; |
| | | |
| | | setTimeout(() => { |
| | | const mockPurchaseData = [ |
| | | { id: 1, date: generateForm.period + "-05", code: "RK2024001", type: "入库", amount: 8000, remark: "原材料采购" }, |
| | | { id: 2, date: generateForm.period + "-10", code: "FK2024001", type: "付款", amount: 5000, remark: "支付货款" }, |
| | | { id: 3, date: generateForm.period + "-15", code: "RK2024002", type: "入库", amount: 12000, remark: "电子元器件" }, |
| | | { id: 4, date: generateForm.period + "-18", code: "TH2024001", type: "退货", amount: 2000, remark: "质量问题退货" }, |
| | | { id: 5, date: generateForm.period + "-22", code: "RK2024003", type: "入库", amount: 6000, remark: "包装材料" }, |
| | | { id: 6, date: generateForm.period + "-25", code: "FK2024002", type: "付款", amount: 8000, remark: "支付货款" }, |
| | | ]; |
| | | |
| | | purchaseData.value = mockPurchaseData; |
| | | |
| | | const lastPeriod = getLastPeriod(generateForm.period); |
| | | const lastStatement = mockData.find(item => |
| | | item.supplierId === generateForm.supplierId && item.period === lastPeriod |
| | | ); |
| | | generateForm.beginBalance = lastStatement ? lastStatement.endBalance : 0; |
| | | |
| | | calculateSummary(); |
| | | |
| | | purchaseLoading.value = false; |
| | | }, 500); |
| | | }; |
| | | |
| | | const getLastPeriod = (period) => { |
| | | const [year, month] = period.split("-").map(Number); |
| | | if (month === 1) { |
| | | return `${year - 1}-12`; |
| | | } |
| | | return `${year}-${String(month - 1).padStart(2, "0")}`; |
| | | }; |
| | | |
| | | const calculateSummary = () => { |
| | | let payable = 0; |
| | | let payment = 0; |
| | | |
| | | selectedPurchases.value.forEach(item => { |
| | | if (item.type === "入库") { |
| | | payable += item.amount; |
| | | } else if (item.type === "退货") { |
| | | payable -= item.amount; |
| | | } else if (item.type === "付款") { |
| | | payment += item.amount; |
| | | } |
| | | }); |
| | | |
| | | generateForm.currentPayable = payable; |
| | | generateForm.currentPayment = payment; |
| | | }; |
| | | |
| | | const handlePurchaseSelectionChange = (selection) => { |
| | | selectedPurchases.value = selection; |
| | | calculateSummary(); |
| | | }; |
| | | |
| | | const confirmGenerate = () => { |
| | | const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1; |
| | | const supplier = supplierList[Math.floor(Math.random() * supplierList.length)]; |
| | | const endBalance = calculateEndBalance(generateForm.beginBalance, generateForm.currentPayable, generateForm.currentPayment); |
| | | |
| | | mockData.unshift({ |
| | | id: newId, |
| | | statementCode: "DZ" + Date.now(), |
| | | supplierId: supplier.id, |
| | | supplierName: supplier.name, |
| | | period: "2024-03", |
| | | beginBalance: Math.floor(Math.random() * 20000), |
| | | currentPayable: Math.floor(Math.random() * 25000), |
| | | currentPayment: Math.floor(Math.random() * 20000), |
| | | endBalance: Math.floor(Math.random() * 25000), |
| | | supplierId: generateForm.supplierId, |
| | | supplierName: generateForm.supplierName, |
| | | period: generateForm.period, |
| | | beginBalance: generateForm.beginBalance, |
| | | currentPayable: generateForm.currentPayable, |
| | | currentPayment: generateForm.currentPayment, |
| | | endBalance, |
| | | }); |
| | | |
| | | generateDialogVisible.value = false; |
| | | ElMessage.success("对账单生成成功"); |
| | | getTableData(); |
| | | }; |
| | | |
| | | const viewDetail = (row) => { |
| | | currentSupplier.value = row.supplierName; |
| | | currentPeriod.value = row.period; |
| | | |
| | | const purchaseInAmount = Math.floor(row.currentPayable * 0.7); |
| | | const returnAmount = Math.floor(row.currentPayable * 0.1); |
| | | const firstPayment = Math.floor(row.currentPayment * 0.5); |
| | | const secondPayment = row.currentPayment - firstPayment; |
| | | |
| | | let runningBalance = row.beginBalance; |
| | | |
| | | detailData.value = [ |
| | | { date: row.period + "-01", type: "期初", code: "-", debit: 0, credit: 0, balance: row.beginBalance, remark: "期初余额" }, |
| | | { date: row.period + "-05", type: "入库", code: "RK2024001", debit: 0, credit: 8000, balance: row.beginBalance + 8000, remark: "" }, |
| | | { date: row.period + "-10", type: "付款", code: "FK2024001", debit: 5000, credit: 0, balance: row.beginBalance + 3000, remark: "" }, |
| | | { date: row.period + "-15", type: "入库", code: "RK2024002", credit: 12000, balance: row.beginBalance + 15000, remark: "" }, |
| | | { date: row.period + "-20", type: "退货", code: "TH2024001", debit: 2000, credit: 0, balance: row.beginBalance + 13000, remark: "" }, |
| | | { date: row.period + "-25", type: "付款", code: "FK2024002", debit: row.currentPayment - 5000, balance: row.endBalance, remark: "" }, |
| | | { date: row.period + "-01", type: "期初", code: "-", debit: 0, credit: 0, balance: runningBalance, remark: "期初余额" }, |
| | | { date: row.period + "-05", type: "入库", code: "RK2024001", debit: 0, credit: purchaseInAmount, balance: runningBalance += purchaseInAmount, remark: "采购入库" }, |
| | | { date: row.period + "-10", type: "付款", code: "FK2024001", debit: firstPayment, credit: 0, balance: runningBalance -= firstPayment, remark: "支付货款" }, |
| | | { date: row.period + "-15", type: "入库", code: "RK2024002", debit: 0, credit: row.currentPayable - purchaseInAmount - returnAmount, balance: runningBalance += (row.currentPayable - purchaseInAmount - returnAmount), remark: "采购入库" }, |
| | | { date: row.period + "-20", type: "退货", code: "TH2024001", debit: 0, credit: -returnAmount, balance: runningBalance -= returnAmount, remark: "采购退货" }, |
| | | { date: row.period + "-25", type: "付款", code: "FK2024002", debit: secondPayment, credit: 0, balance: runningBalance -= secondPayment, remark: "支付货款" }, |
| | | ]; |
| | | |
| | | detailDialogVisible.value = true; |
| | | }; |
| | | |
| | |
| | | margin: 0; |
| | | } |
| | | } |
| | | |
| | | .purchase-section { |
| | | margin-top: 20px; |
| | | |
| | | .section-title { |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | margin-bottom: 15px; |
| | | padding-left: 10px; |
| | | border-left: 4px solid #409eff; |
| | | } |
| | | } |
| | | |
| | | .summary-row { |
| | | display: flex; |
| | | justify-content: space-around; |
| | | padding: 15px; |
| | | background-color: #f5f7fa; |
| | | border-radius: 4px; |
| | | margin-top: 15px; |
| | | |
| | | span { |
| | | font-size: 14px; |
| | | |
| | | strong { |
| | | font-size: 16px; |
| | | margin-left: 5px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .empty-tip { |
| | | margin-top: 30px; |
| | | } |
| | | |
| | | .text-primary { |
| | | color: #409eff; |
| | | } |
| | | </style> |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "开票申请", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "销项发票", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "收款单", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog title="对账明细" v-model="detailDialogVisible" width="900px" append-to-body> |
| | | <FormDialog title="对账明细" v-model="detailDialogVisible" width="900px" @confirm="printDetail" @cancel="detailDialogVisible = false" operationType="detail"> |
| | | <div class="statement-header"> |
| | | <h3>{{ currentCustomer }} 应收对账单</h3> |
| | | <p>对账期间: {{ currentPeriod }}</p> |
| | |
| | | <el-table-column prop="remark" label="备注" show-overflow-tooltip /> |
| | | </el-table> |
| | | <template #footer> |
| | | <el-button @click="detailDialogVisible = false">关闭</el-button> |
| | | <el-button type="primary" @click="printDetail">打印</el-button> |
| | | <el-button @click="detailDialogVisible = false">关闭</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | |
| | | <FormDialog title="生成对账单" v-model="generateDialogVisible" width="1000px" @confirm="confirmGenerate" @cancel="generateDialogVisible = false"> |
| | | <el-form :model="generateForm" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="选择客户" prop="customerId"> |
| | | <el-select v-model="generateForm.customerId" placeholder="请选择客户" style="width: 100%;" @change="onCustomerChange"> |
| | | <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="对账月份" prop="period"> |
| | | <el-date-picker v-model="generateForm.period" type="month" placeholder="选择月份" value-format="YYYY-MM" style="width: 100%;" @change="onPeriodChange" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <div v-if="salesData.length > 0" class="sales-section"> |
| | | <div class="section-title">本月销售数据</div> |
| | | <el-table :data="salesData" border style="width: 100%; margin-bottom: 15px;" v-loading="salesLoading" @selection-change="handleSalesSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column prop="date" label="日期" width="120" /> |
| | | <el-table-column prop="code" label="单据编号" width="150" /> |
| | | <el-table-column prop="type" label="类型" width="100"> |
| | | <template #default="{ row }"> |
| | | <el-tag :type="row.type === '出库' ? 'success' : row.type === '收款' ? 'primary' : 'danger'">{{ row.type }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="amount" label="金额" width="120"> |
| | | <template #default="{ row }"> |
| | | <span :class="row.type === '出库' ? 'text-primary' : row.type === '收款' ? 'text-success' : 'text-danger'">¥{{ formatMoney(row.amount) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="remark" label="备注" /> |
| | | </el-table> |
| | | |
| | | <div class="summary-row"> |
| | | <span>期初余额: <strong class="text-primary">¥{{ formatMoney(generateForm.beginBalance) }}</strong></span> |
| | | <span>本期应收: <strong class="text-primary">¥{{ formatMoney(generateForm.currentReceivable) }}</strong></span> |
| | | <span>本期收款: <strong class="text-success">¥{{ formatMoney(generateForm.currentReceipt) }}</strong></span> |
| | | <span>期末余额: <strong :class="calculateEndBalance(generateForm.beginBalance, generateForm.currentReceivable, generateForm.currentReceipt) >= 0 ? 'text-success' : 'text-danger'">¥{{ formatMoney(calculateEndBalance(generateForm.beginBalance, generateForm.currentReceivable, generateForm.currentReceipt)) }}</strong></span> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-else-if="generateForm.customerId && !salesLoading" class="empty-tip"> |
| | | <el-empty description="该客户本月暂无销售数据" /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <el-button type="primary" @click="confirmGenerate" :disabled="!canGenerate">确认生成</el-button> |
| | | <el-button @click="generateDialogVisible = false">取消</el-button> |
| | | </template> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "应收对账", |
| | |
| | | const currentPeriod = ref(""); |
| | | const detailData = ref([]); |
| | | |
| | | const generateDialogVisible = ref(false); |
| | | const salesLoading = ref(false); |
| | | const salesData = ref([]); |
| | | const selectedSales = ref([]); |
| | | |
| | | const generateForm = reactive({ |
| | | customerId: "", |
| | | customerName: "", |
| | | period: "", |
| | | beginBalance: 0, |
| | | currentReceivable: 0, |
| | | currentReceipt: 0, |
| | | }); |
| | | |
| | | const canGenerate = computed(() => { |
| | | return generateForm.customerId && generateForm.period && selectedSales.value.length > 0; |
| | | }); |
| | | |
| | | const customerList = [ |
| | | { id: 1, name: "北京科技有限公司" }, |
| | | { id: 2, name: "上海贸易公司" }, |
| | |
| | | { id: 2, statementCode: "DZ202401002", customerId: 2, customerName: "上海贸易公司", period: "2024-01", beginBalance: 5000, currentReceivable: 12000, currentReceipt: 10000, endBalance: 7000 }, |
| | | { id: 3, statementCode: "DZ202402001", customerId: 1, customerName: "北京科技有限公司", period: "2024-02", beginBalance: 17000, currentReceivable: 20000, currentReceipt: 15000, endBalance: 22000 }, |
| | | ]; |
| | | |
| | | const calculateEndBalance = (beginBalance, currentReceivable, currentReceipt) => { |
| | | return beginBalance + currentReceivable - currentReceipt; |
| | | }; |
| | | |
| | | const formatMoney = (value) => { |
| | | if (value === undefined || value === null) return "0.00"; |
| | |
| | | }; |
| | | |
| | | const generateStatement = () => { |
| | | ElMessage.success("对账单生成成功"); |
| | | generateForm.customerId = ""; |
| | | generateForm.customerName = ""; |
| | | generateForm.period = ""; |
| | | generateForm.beginBalance = 0; |
| | | generateForm.currentReceivable = 0; |
| | | generateForm.currentReceipt = 0; |
| | | salesData.value = []; |
| | | selectedSales.value = []; |
| | | generateDialogVisible.value = true; |
| | | }; |
| | | |
| | | const onCustomerChange = (customerId) => { |
| | | const customer = customerList.find(item => item.id === customerId); |
| | | if (customer) { |
| | | generateForm.customerName = customer.name; |
| | | } |
| | | loadSalesData(); |
| | | }; |
| | | |
| | | const onPeriodChange = () => { |
| | | loadSalesData(); |
| | | }; |
| | | |
| | | const loadSalesData = () => { |
| | | if (!generateForm.customerId || !generateForm.period) { |
| | | salesData.value = []; |
| | | return; |
| | | } |
| | | |
| | | salesLoading.value = true; |
| | | |
| | | setTimeout(() => { |
| | | const mockSalesData = [ |
| | | { id: 1, date: generateForm.period + "-03", code: "CK2024001", type: "出库", amount: 8000, remark: "产品A销售" }, |
| | | { id: 2, date: generateForm.period + "-08", code: "SK2024001", type: "收款", amount: 5000, remark: "客户回款" }, |
| | | { id: 3, date: generateForm.period + "-12", code: "CK2024002", type: "出库", amount: 12000, remark: "产品B销售" }, |
| | | { id: 4, date: generateForm.period + "-15", code: "TH2024001", type: "退货", amount: 2000, remark: "质量问题退货" }, |
| | | { id: 5, date: generateForm.period + "-20", code: "CK2024003", type: "出库", amount: 5000, remark: "产品C销售" }, |
| | | { id: 6, date: generateForm.period + "-25", code: "SK2024002", type: "收款", amount: 8000, remark: "客户回款" }, |
| | | ]; |
| | | |
| | | salesData.value = mockSalesData; |
| | | |
| | | const lastPeriod = getLastPeriod(generateForm.period); |
| | | const lastStatement = mockData.find(item => |
| | | item.customerId === generateForm.customerId && item.period === lastPeriod |
| | | ); |
| | | generateForm.beginBalance = lastStatement ? lastStatement.endBalance : 0; |
| | | |
| | | calculateSummary(); |
| | | |
| | | salesLoading.value = false; |
| | | }, 500); |
| | | }; |
| | | |
| | | const getLastPeriod = (period) => { |
| | | const [year, month] = period.split("-").map(Number); |
| | | if (month === 1) { |
| | | return `${year - 1}-12`; |
| | | } |
| | | return `${year}-${String(month - 1).padStart(2, "0")}`; |
| | | }; |
| | | |
| | | const calculateSummary = () => { |
| | | let receivable = 0; |
| | | let receipt = 0; |
| | | |
| | | selectedSales.value.forEach(item => { |
| | | if (item.type === "出库") { |
| | | receivable += item.amount; |
| | | } else if (item.type === "退货") { |
| | | receivable -= item.amount; |
| | | } else if (item.type === "收款") { |
| | | receipt += item.amount; |
| | | } |
| | | }); |
| | | |
| | | generateForm.currentReceivable = receivable; |
| | | generateForm.currentReceipt = receipt; |
| | | }; |
| | | |
| | | const handleSalesSelectionChange = (selection) => { |
| | | selectedSales.value = selection; |
| | | calculateSummary(); |
| | | }; |
| | | |
| | | const confirmGenerate = () => { |
| | | const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1; |
| | | const customer = customerList[Math.floor(Math.random() * customerList.length)]; |
| | | const endBalance = calculateEndBalance(generateForm.beginBalance, generateForm.currentReceivable, generateForm.currentReceipt); |
| | | |
| | | mockData.unshift({ |
| | | id: newId, |
| | | statementCode: "DZ" + Date.now(), |
| | | customerId: customer.id, |
| | | customerName: customer.name, |
| | | period: "2024-03", |
| | | beginBalance: Math.floor(Math.random() * 10000), |
| | | currentReceivable: Math.floor(Math.random() * 20000), |
| | | currentReceipt: Math.floor(Math.random() * 15000), |
| | | endBalance: Math.floor(Math.random() * 20000), |
| | | customerId: generateForm.customerId, |
| | | customerName: generateForm.customerName, |
| | | period: generateForm.period, |
| | | beginBalance: generateForm.beginBalance, |
| | | currentReceivable: generateForm.currentReceivable, |
| | | currentReceipt: generateForm.currentReceipt, |
| | | endBalance, |
| | | }); |
| | | |
| | | generateDialogVisible.value = false; |
| | | ElMessage.success("对账单生成成功"); |
| | | getTableData(); |
| | | }; |
| | | |
| | | const viewDetail = (row) => { |
| | | currentCustomer.value = row.customerName; |
| | | currentPeriod.value = row.period; |
| | | |
| | | const saleOutAmount = Math.floor(row.currentReceivable * 0.6); |
| | | const returnAmount = Math.floor(row.currentReceivable * 0.1); |
| | | const firstReceipt = Math.floor(row.currentReceipt * 0.4); |
| | | const secondReceipt = row.currentReceipt - firstReceipt; |
| | | |
| | | let runningBalance = row.beginBalance; |
| | | |
| | | detailData.value = [ |
| | | { date: row.period + "-01", type: "期初", code: "-", debit: 0, credit: 0, balance: row.beginBalance, remark: "期初余额" }, |
| | | { date: row.period + "-05", type: "出库", code: "CK2024001", debit: 5000, credit: 0, balance: row.beginBalance + 5000, remark: "" }, |
| | | { date: row.period + "-10", type: "收款", code: "SK2024001", debit: 0, credit: 3000, balance: row.beginBalance + 2000, remark: "" }, |
| | | { date: row.period + "-15", type: "出库", code: "CK2024002", debit: 8000, credit: 0, balance: row.beginBalance + 10000, remark: "" }, |
| | | { date: row.period + "-20", type: "退货", code: "TH2024001", debit: 0, credit: 2000, balance: row.beginBalance + 8000, remark: "" }, |
| | | { date: row.period + "-25", type: "收款", code: "SK2024002", credit: row.currentReceipt - 3000, balance: row.endBalance, remark: "" }, |
| | | { date: row.period + "-01", type: "期初", code: "-", debit: 0, credit: 0, balance: runningBalance, remark: "期初余额" }, |
| | | { date: row.period + "-05", type: "出库", code: "CK2024001", debit: saleOutAmount, credit: 0, balance: runningBalance += saleOutAmount, remark: "销售出库" }, |
| | | { date: row.period + "-10", type: "收款", code: "SK2024001", debit: 0, credit: firstReceipt, balance: runningBalance -= firstReceipt, remark: "客户回款" }, |
| | | { date: row.period + "-15", type: "出库", code: "CK2024002", debit: row.currentReceivable - saleOutAmount - returnAmount, credit: 0, balance: runningBalance += (row.currentReceivable - saleOutAmount - returnAmount), remark: "销售出库" }, |
| | | { date: row.period + "-20", type: "退货", code: "TH2024001", debit: 0, credit: returnAmount, balance: runningBalance -= returnAmount, remark: "销售退货" }, |
| | | { date: row.period + "-25", type: "收款", code: "SK2024002", debit: 0, credit: secondReceipt, balance: runningBalance -= secondReceipt, remark: "客户回款" }, |
| | | ]; |
| | | |
| | | detailDialogVisible.value = true; |
| | | }; |
| | | |
| | |
| | | margin: 0; |
| | | } |
| | | } |
| | | |
| | | .sales-section { |
| | | margin-top: 20px; |
| | | |
| | | .section-title { |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | margin-bottom: 15px; |
| | | padding-left: 10px; |
| | | border-left: 4px solid #409eff; |
| | | } |
| | | } |
| | | |
| | | .summary-row { |
| | | display: flex; |
| | | justify-content: space-around; |
| | | padding: 15px; |
| | | background-color: #f5f7fa; |
| | | border-radius: 4px; |
| | | margin-top: 15px; |
| | | |
| | | span { |
| | | font-size: 14px; |
| | | |
| | | strong { |
| | | font-size: 16px; |
| | | margin-left: 5px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .empty-tip { |
| | | margin-top: 30px; |
| | | } |
| | | </style> |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "销售出库", |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" append-to-body> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="800px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm">确定</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "销售退货", |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" title="收款/退款" width="90%" append-to-body> |
| | | <FormDialog v-model="visible" title="收款/退款" width="90%" @confirm="submit" @cancel="visible=false"> |
| | | <div class="section"> |
| | | <div class="section-title descriptions">基础资料</div> |
| | | <el-form :model="form" label-width="100px"> |
| | |
| | | <el-button type="primary" @click="submit">确认</el-button> |
| | | <el-button @click="visible=false">取消</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import { getToken } from '@/utils/auth'; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | const visible = ref(false); |
| | | const form = ref({ |
| | |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <el-dialog :title="dialogTitle" v-model="dialogVisible" width="900px" append-to-body> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="100px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="凭证字号" prop="voucherNo"> |
| | | <el-input v-model="form.voucherNo" placeholder="系统自动生成" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="凭证日期" prop="voucherDate"> |
| | | <el-date-picker v-model="form.voucherDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="附件张数" prop="attachmentCount"> |
| | | <el-input-number v-model="form.attachmentCount" :min="0" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="凭证分录" prop="entries"> |
| | | <el-table :data="form.entries" border style="width: 100%"> |
| | | <el-table-column type="index" label="序号" width="60" /> |
| | | <el-table-column prop="subjectCode" label="科目编码" width="120"> |
| | | <template #default="{ $index }"> |
| | | <el-select v-model="form.entries[$index].subjectCode" placeholder="选择科目" filterable style="width: 100%;" @change="(val) => handleSubjectChange(val, $index)"> |
| | | <el-option v-for="item in subjectList" :key="item.code" :label="item.code" :value="item.code" /> |
| | | <FormDialog :title="dialogTitle" v-model="dialogVisible" width="1200px" @confirm="submitForm" @cancel="dialogVisible = false"> |
| | | <div class="voucher-container"> |
| | | <div class="voucher-header"> |
| | | <h2 class="voucher-title">记账凭证</h2> |
| | | <div class="voucher-period">{{ form.voucherDate ? form.voucherDate.substring(0, 7) + '期' : '' }}</div> |
| | | </div> |
| | | <el-form :model="form" :rules="rules" ref="formRef" label-width="0"> |
| | | <div class="voucher-info"> |
| | | <div class="voucher-no-section"> |
| | | <span class="label">凭证字:</span> |
| | | <el-select v-model="form.voucherPrefix" style="width: 70px;"> |
| | | <el-option label="记" value="记" /> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="subjectName" label="科目名称" width="150"> |
| | | <template #default="{ $index }"> |
| | | <el-input v-model="form.entries[$index].subjectName" disabled /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="summary" label="摘要"> |
| | | <template #default="{ $index }"> |
| | | <el-input v-model="form.entries[$index].summary" placeholder="请输入摘要" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="debit" label="借方金额" width="130"> |
| | | <template #default="{ $index }"> |
| | | <el-input-number v-model="form.entries[$index].debit" :min="0" :precision="2" style="width: 100%;" @change="calculateTotal" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="credit" label="贷方金额" width="130"> |
| | | <template #default="{ $index }"> |
| | | <el-input-number v-model="form.entries[$index].credit" :min="0" :precision="2" style="width: 100%;" @change="calculateTotal" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="80"> |
| | | <template #default="{ $index }"> |
| | | <el-button type="danger" link @click="removeEntry($index)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div style="display: flex; justify-content: space-between; margin-top: 10px;"> |
| | | <el-button type="primary" link @click="addEntry">+ 添加分录</el-button> |
| | | <div> |
| | | <span style="margin-right: 20px;">合计: 借方 <span :class="totalDebitEntry === totalCreditEntry ? 'text-success' : 'text-danger'">¥{{ formatMoney(totalDebitEntry) }}</span></span> |
| | | <span>贷方 <span :class="totalDebitEntry === totalCreditEntry ? 'text-success' : 'text-danger'">¥{{ formatMoney(totalCreditEntry) }}</span></span> |
| | | <el-input v-model="form.voucherNum" style="width: 60px;" /> |
| | | <span class="label" style="margin-left: 5px;">号</span> |
| | | </div> |
| | | <div class="voucher-date-section"> |
| | | <span class="label">日期:</span> |
| | | <el-date-picker v-model="form.voucherDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 140px;" /> |
| | | </div> |
| | | <div class="voucher-attachment-section"> |
| | | <span class="label">附件:</span> |
| | | <el-input-number v-model="form.attachmentCount" :min="0" :controls="false" style="width: 60px;" /> |
| | | <span class="label" style="margin-left: 5px;">张</span> |
| | | <el-button type="primary" link style="margin-left: 10px;">上传文件</el-button> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item label="制单人" prop="creator"> |
| | | <el-input v-model="form.creator" disabled /> |
| | | </el-form-item> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" /> |
| | | </el-form-item> |
| | | <div class="voucher-table"> |
| | | <table class="accounting-voucher"> |
| | | <thead> |
| | | <tr> |
| | | <th class="col-summary" rowspan="2">摘要</th> |
| | | <th class="col-subject" rowspan="2">会计科目</th> |
| | | <th class="col-debit-header" colspan="11">借方</th> |
| | | <th class="col-credit-header" colspan="11">贷方</th> |
| | | <th class="col-action" rowspan="2">操作</th> |
| | | </tr> |
| | | <tr class="amount-header"> |
| | | <th>亿</th> |
| | | <th>千</th> |
| | | <th>百</th> |
| | | <th>十</th> |
| | | <th>万</th> |
| | | <th>千</th> |
| | | <th>百</th> |
| | | <th>十</th> |
| | | <th>元</th> |
| | | <th>角</th> |
| | | <th>分</th> |
| | | <th>亿</th> |
| | | <th>千</th> |
| | | <th>百</th> |
| | | <th>十</th> |
| | | <th>万</th> |
| | | <th>千</th> |
| | | <th>百</th> |
| | | <th>十</th> |
| | | <th>元</th> |
| | | <th>角</th> |
| | | <th>分</th> |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | <tr v-for="(entry, rowIndex) in form.entries" :key="rowIndex" @click="selectRow(rowIndex)" :class="{ 'selected-row': selectedRowIndex === rowIndex }"> |
| | | <td class="col-summary"> |
| | | <el-input v-model="entry.summary" placeholder="请输入摘要" @focus="selectRow(rowIndex)" /> |
| | | </td> |
| | | <td class="col-subject"> |
| | | <el-select v-model="entry.subjectCode" placeholder="选择科目" filterable @change="(val) => handleSubjectChange(val, rowIndex)" @focus="selectRow(rowIndex)"> |
| | | <el-option v-for="item in subjectList" :key="item.code" :label="item.code + item.name" :value="item.code" /> |
| | | </el-select> |
| | | <div class="subject-name">{{ entry.subjectName }}</div> |
| | | </td> |
| | | <!-- 借方11列 --> |
| | | <template v-if="editingCell.row === rowIndex && editingCell.type === 'debit'"> |
| | | <td colspan="11" class="debit-input-cell"> |
| | | <el-input-number ref="amountInputRef" v-model="entry.debit" :min="0" :precision="2" :controls="false" size="small" @blur="finishEdit" class="full-width-input" /> |
| | | </td> |
| | | </template> |
| | | <template v-else> |
| | | <td v-for="(digit, dIndex) in getAmountDigits(entry.debit, 11)" :key="'debit-'+dIndex" class="amount-cell debit-cell" @click="openAmountInput(rowIndex, 'debit')"> |
| | | <span :class="{ 'text-primary': digit !== '', 'zero': digit === '' }">{{ digit || '' }}</span> |
| | | </td> |
| | | </template> |
| | | <!-- 贷方11列 --> |
| | | <template v-if="editingCell.row === rowIndex && editingCell.type === 'credit'"> |
| | | <td colspan="11" class="credit-input-cell"> |
| | | <el-input-number ref="amountInputRef" v-model="entry.credit" :min="0" :precision="2" :controls="false" size="small" @blur="finishEdit" class="full-width-input" /> |
| | | </td> |
| | | </template> |
| | | <template v-else> |
| | | <td v-for="(digit, dIndex) in getAmountDigits(entry.credit, 11)" :key="'credit-'+dIndex" class="amount-cell credit-cell" @click="openAmountInput(rowIndex, 'credit')"> |
| | | <span :class="{ 'text-danger': digit !== '', 'zero': digit === '' }">{{ digit || '' }}</span> |
| | | </td> |
| | | </template> |
| | | <td class="col-action"> |
| | | <el-button type="danger" link size="small" @click="removeEntry(rowIndex)" icon="Delete" :disabled="form.entries.length <= 2">删除</el-button> |
| | | </td> |
| | | </tr> |
| | | <tr class="total-row"> |
| | | <td class="col-summary" colspan="2" style="text-align: center; font-weight: bold;">合计:</td> |
| | | <td v-for="(digit, index) in getAmountDigits(totalDebitEntry, 11)" :key="'total-debit-'+index" class="amount-cell total-debit-cell"> |
| | | <span :class="{ 'text-primary': digit !== '' }">{{ digit }}</span> |
| | | </td> |
| | | <td v-for="(digit, index) in getAmountDigits(totalCreditEntry, 11)" :key="'total-credit-'+index" class="amount-cell total-credit-cell"> |
| | | <span :class="{ 'text-danger': digit !== '' }">{{ digit }}</span> |
| | | </td> |
| | | <td class="col-action"></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | <div class="voucher-toolbar"> |
| | | <el-button type="primary" link @click="addEntry" icon="Plus">新增行</el-button> |
| | | </div> |
| | | <div class="voucher-footer"> |
| | | <div class="creator-section"> |
| | | <span class="label">制单人:{{ form.creator }}</span> |
| | | </div> |
| | | </div> |
| | | </el-form> |
| | | </div> |
| | | <template #footer> |
| | | <div> |
| | | <el-button type="primary" @click="submitForm" :disabled="!isBalanced">保存</el-button> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="submitForm" :disabled="totalDebitEntry !== totalCreditEntry">确定</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, computed } from "vue"; |
| | | import { ref, reactive, onMounted, computed, nextTick } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | |
| | | defineOptions({ |
| | | name: "凭证管理", |
| | |
| | | |
| | | const form = reactive({ |
| | | voucherNo: "", |
| | | voucherPrefix: "记", |
| | | voucherNum: "", |
| | | voucherDate: "", |
| | | attachmentCount: 0, |
| | | entries: [], |
| | | creator: "张三", |
| | | remark: "", |
| | | }); |
| | | |
| | | const selectedRowIndex = ref(-1); |
| | | const editingCell = reactive({ |
| | | row: -1, |
| | | type: "", |
| | | }); |
| | | const amountInputRef = ref(null); |
| | | |
| | | const isBalanced = computed(() => { |
| | | return totalDebitEntry.value === totalCreditEntry.value && totalDebitEntry.value > 0; |
| | | }); |
| | | |
| | | const rules = { |
| | |
| | | form.entries.push({ subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }); |
| | | }; |
| | | |
| | | const selectRow = (index) => { |
| | | selectedRowIndex.value = index; |
| | | }; |
| | | |
| | | const openAmountInput = (index, type) => { |
| | | editingCell.row = index; |
| | | editingCell.type = type; |
| | | nextTick(() => { |
| | | if (amountInputRef.value) { |
| | | amountInputRef.value.focus(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const finishEdit = () => { |
| | | editingCell.row = -1; |
| | | editingCell.type = ""; |
| | | }; |
| | | |
| | | const getAmountDigits = (amount, length) => { |
| | | if (!amount || amount === 0) { |
| | | return new Array(length).fill(''); |
| | | } |
| | | |
| | | const amountStr = Number(amount).toFixed(2); |
| | | const [intPart, decPart] = amountStr.split('.'); |
| | | const fullAmount = intPart + decPart; |
| | | |
| | | // 左填充0到指定长度 |
| | | const paddedAmount = fullAmount.padStart(length, '0'); |
| | | const digits = paddedAmount.split(''); |
| | | |
| | | // 找到第一个非零数字的位置 |
| | | let firstNonZeroIndex = 0; |
| | | for (let i = 0; i < digits.length; i++) { |
| | | if (digits[i] !== '0') { |
| | | firstNonZeroIndex = i; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // 只隐藏前导零(第一个非零数字之前的零) |
| | | return digits.map((d, index) => { |
| | | if (index < firstNonZeroIndex) { |
| | | return ''; // 前导零显示为空 |
| | | } |
| | | return d; // 保留金额中的零 |
| | | }); |
| | | }; |
| | | |
| | | const removeEntry = (index) => { |
| | | form.entries.splice(index, 1); |
| | | calculateTotal(); |
| | |
| | | const add = () => { |
| | | isEdit.value = false; |
| | | dialogTitle.value = "新增凭证"; |
| | | const nextNum = String(mockData.length + 1).padStart(2, "0"); |
| | | Object.assign(form, { |
| | | voucherNo: "记-" + String(mockData.length + 1).padStart(4, "0"), |
| | | voucherNo: "记-" + nextNum, |
| | | voucherPrefix: "记", |
| | | voucherNum: nextNum, |
| | | voucherDate: new Date().toISOString().split('T')[0], |
| | | attachmentCount: 0, |
| | | entries: [{ subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }], |
| | | entries: [ |
| | | { subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }, |
| | | { subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }, |
| | | { subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }, |
| | | { subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }, |
| | | ], |
| | | creator: "张三", |
| | | remark: "", |
| | | }); |
| | | selectedRowIndex.value = 0; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | |
| | | isEdit.value = true; |
| | | currentId.value = row.id; |
| | | dialogTitle.value = "编辑凭证"; |
| | | Object.assign(form, row); |
| | | const parts = row.voucherNo.split('-'); |
| | | Object.assign(form, { |
| | | ...row, |
| | | voucherPrefix: parts[0] || '记', |
| | | voucherNum: parts[1] || '', |
| | | }); |
| | | if (form.entries.length < 4) { |
| | | while (form.entries.length < 4) { |
| | | form.entries.push({ subjectCode: "", subjectName: "", summary: "", debit: 0, credit: 0 }); |
| | | } |
| | | } |
| | | selectedRowIndex.value = 0; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | |
| | | const submitForm = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (valid) { |
| | | if (totalDebitEntry.value !== totalCreditEntry.value) { |
| | | if (!isBalanced.value) { |
| | | ElMessage.error("借贷不平衡,请检查分录"); |
| | | return; |
| | | } |
| | | const summary = form.entries.find(e => e.debit > 0)?.summary || ""; |
| | | |
| | | const validEntries = form.entries.filter(e => e.subjectCode && (e.debit > 0 || e.credit > 0)); |
| | | const summary = validEntries.find(e => e.debit > 0)?.summary || ""; |
| | | |
| | | const voucherNo = `${form.voucherPrefix}-${form.voucherNum}`; |
| | | const dataToSave = { |
| | | ...form, |
| | | voucherNo, |
| | | summary, |
| | | debit: totalDebitEntry.value, |
| | | credit: totalCreditEntry.value, |
| | | entries: validEntries, |
| | | }; |
| | | |
| | | if (isEdit.value) { |
| | | const index = mockData.findIndex(item => item.id === currentId.value); |
| | | if (index !== -1) { |
| | | mockData[index] = { ...mockData[index], ...form, summary, debit: totalDebitEntry.value, credit: totalCreditEntry.value }; |
| | | mockData[index] = { ...mockData[index], ...dataToSave }; |
| | | } |
| | | ElMessage.success("编辑成功"); |
| | | } else { |
| | | const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1; |
| | | mockData.push({ id: newId, ...form, summary, debit: totalDebitEntry.value, credit: totalCreditEntry.value, status: "unposted" }); |
| | | mockData.push({ id: newId, ...dataToSave, status: "unposted" }); |
| | | ElMessage.success("新增成功"); |
| | | } |
| | | dialogVisible.value = false; |
| | |
| | | color: #f56c6c; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .text-primary { |
| | | color: #409eff; |
| | | } |
| | | |
| | | .voucher-container { |
| | | background: #fff; |
| | | padding: 20px; |
| | | } |
| | | |
| | | .voucher-header { |
| | | text-align: center; |
| | | margin-bottom: 15px; |
| | | |
| | | .voucher-title { |
| | | font-size: 22px; |
| | | font-weight: bold; |
| | | margin: 0 0 5px 0; |
| | | color: #303133; |
| | | } |
| | | |
| | | .voucher-period { |
| | | font-size: 14px; |
| | | color: #909399; |
| | | } |
| | | } |
| | | |
| | | .voucher-info { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | padding: 0 10px; |
| | | |
| | | .label { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | } |
| | | |
| | | .voucher-no-section, |
| | | .voucher-date-section, |
| | | .voucher-attachment-section { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | |
| | | .voucher-table { |
| | | border: 1px solid #dcdfe6; |
| | | border-right: none; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .accounting-voucher { |
| | | width: 100%; |
| | | border-collapse: collapse; |
| | | font-size: 13px; |
| | | |
| | | th, |
| | | td { |
| | | border: 1px solid #dcdfe6; |
| | | text-align: center; |
| | | padding: 0; |
| | | height: 36px; |
| | | } |
| | | |
| | | & th:last-child, |
| | | & td:last-child { |
| | | border-right: none !important; |
| | | } |
| | | |
| | | thead { |
| | | background-color: #f5f7fa; |
| | | |
| | | th { |
| | | font-weight: normal; |
| | | color: #606266; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .col-summary, |
| | | .col-subject { |
| | | font-weight: bold; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | .col-debit-header, |
| | | .col-credit-header { |
| | | background-color: #ecf5ff; |
| | | color: #409eff; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | |
| | | .amount-header { |
| | | th { |
| | | font-size: 11px; |
| | | padding: 2px 0; |
| | | background-color: #f5f7fa; |
| | | } |
| | | } |
| | | |
| | | .col-summary { |
| | | width: 160px; |
| | | min-width: 160px; |
| | | } |
| | | |
| | | .col-subject { |
| | | width: 180px; |
| | | min-width: 180px; |
| | | } |
| | | |
| | | .col-action { |
| | | width: 60px; |
| | | min-width: 60px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .amount-cell { |
| | | width: 24px; |
| | | min-width: 24px; |
| | | max-width: 24px; |
| | | padding: 0; |
| | | font-size: 13px; |
| | | font-family: 'Courier New', monospace; |
| | | cursor: pointer; |
| | | text-align: center; |
| | | |
| | | &:hover { |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | span { |
| | | display: block; |
| | | width: 100%; |
| | | height: 100%; |
| | | line-height: 36px; |
| | | |
| | | &.zero { |
| | | color: #c0c4cc; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .debit-input-cell, |
| | | .credit-input-cell { |
| | | padding: 0; |
| | | background-color: #ecf5ff; |
| | | |
| | | .full-width-input { |
| | | width: 100%; |
| | | |
| | | :deep(.el-input__wrapper) { |
| | | padding: 0 10px; |
| | | box-shadow: none; |
| | | background-color: transparent; |
| | | } |
| | | |
| | | input { |
| | | text-align: right; |
| | | font-size: 14px; |
| | | height: 34px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | tbody { |
| | | tr { |
| | | &:hover { |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | &.selected-row { |
| | | background-color: #ecf5ff; |
| | | } |
| | | } |
| | | |
| | | td { |
| | | .el-input { |
| | | .el-input__wrapper { |
| | | box-shadow: none; |
| | | padding: 0 5px; |
| | | } |
| | | |
| | | input { |
| | | text-align: center; |
| | | height: 34px; |
| | | } |
| | | } |
| | | |
| | | .el-select { |
| | | width: 100%; |
| | | |
| | | .el-input__wrapper { |
| | | box-shadow: none; |
| | | } |
| | | |
| | | input { |
| | | text-align: center; |
| | | height: 34px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .col-summary { |
| | | .el-input input { |
| | | text-align: left; |
| | | padding-left: 10px; |
| | | } |
| | | } |
| | | |
| | | .col-subject { |
| | | position: relative; |
| | | |
| | | .el-select { |
| | | .el-input input { |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | |
| | | .subject-name { |
| | | font-size: 11px; |
| | | color: #909399; |
| | | margin-top: 2px; |
| | | line-height: 1.2; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .total-row { |
| | | background-color: #fdf6ec; |
| | | |
| | | td { |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .total-cell { |
| | | background-color: #fdf6ec; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .voucher-toolbar { |
| | | display: flex; |
| | | justify-content: flex-start; |
| | | padding: 10px 0; |
| | | margin-top: 5px; |
| | | } |
| | | |
| | | .voucher-footer { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | padding: 0 10px; |
| | | margin-top: 10px; |
| | | |
| | | .creator-section { |
| | | .label { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | } |
| | | } |
| | | } |
| | | |
| | | :deep(.el-dialog__body) { |
| | | padding: 10px 20px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <div class="search_form" style="margin-bottom: 10px;"> |
| | | <div> |
| | | <span class="search_title ml10">出库日期:</span> |
| | | <el-date-picker |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <div class="search_form" style="margin-bottom: 10px;"> |
| | | <div> |
| | | <span class="search_title ml10">入库日期:</span> |
| | | <el-date-picker v-model="searchForm.timeStr" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <div class="search_form mb10"> |
| | | <div> |
| | | <span class="search_title ml10">产品大类:</span> |
| | | <el-input v-model="searchForm.productName" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">发放季度:</span> |
| | | <el-select |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">姓名:</span> |
| | | <el-input v-model="searchForm.staffName" style="width: 240px" placeholder="请输入姓名搜索" @change="handleQuery" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">姓名:</span> |
| | | <el-input |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">姓名:</span> |
| | | <el-input |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">主题:</span> |
| | | <el-input |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form" style="margin-bottom: 20px;"> |
| | | <div> |
| | | <span class="search_title">供应商名称:</span> |
| | | <el-input |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {Search, Delete} from "@element-plus/icons-vue"; |
| | | import FormDialog from '@/components/Dialog/FormDialog.vue'; |
| | | import FileListDialog from '@/components/Dialog/FileListDialog.vue'; |
| | | import { getToken } from "@/utils/auth"; |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | padding: 20px; |
| | | background-color: #f5f7fa; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | .page-header { |
| | | text-align: center; |
| | | margin-bottom: 20px; |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div class="search-row"> |
| | | <div class="search-item"> |
| | | <span class="search_title">工单编号:</span> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div class="search-row"> |
| | | <div class="search-item"> |
| | | <span class="search_title">工单编号:</span> |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">产品名称:</span> |
| | | <el-input |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div style="display: flex;flex-direction: row;align-items: center;"> |
| | | <div> |
| | | <span class="search_title">类型:</span> |
| | | <el-form :model="searchForm" inline style="margin-bottom: 0;"> |
| | | <el-form-item label="类型:"> |
| | | <el-select v-model="searchForm.inspectType" clearable style="width: 200px" @change="handleQuery"> |
| | | <el-option label="原材料检验" :value="0" /> |
| | | <el-option label="过程检验" :value="1" /> |
| | | <el-option label="出厂检验" :value="2" /> |
| | | </el-select> |
| | | </div> |
| | | <div style="margin-left: 10px"> |
| | | <span class="search_title">状态:</span> |
| | | </el-form-item> |
| | | <el-form-item label="状态:"> |
| | | <el-select v-model="searchForm.inspectState" clearable style="width: 200px" @change="handleQuery"> |
| | | <el-option label="待处理" :value="0" /> |
| | | <el-option label="已处理" :value="1" /> |
| | | </el-select> |
| | | </div> |
| | | <div style="margin-left: 10px"> |
| | | <span class="search_title">产品名称:</span> |
| | | </el-form-item> |
| | | <el-form-item label="产品名称:"> |
| | | <el-input |
| | | v-model="searchForm.productName" |
| | | style="width: 200px" |
| | |
| | | clearable |
| | | :prefix-icon="Search" |
| | | /> |
| | | </div> |
| | | <span style="margin-left: 10px" class="search_title">检测日期:</span> |
| | | </el-form-item> |
| | | <el-form-item label="检测日期:"> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | style="width: 300px" |
| | | placeholder="请选择" clearable @change="changeDaterange" /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery">搜索</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div> |
| | | <div class="mb20" style="text-align: right;"> |
| | | <el-button type="primary" @click="openForm('add')">新增</el-button> |
| | | <el-button @click="handleOut">导出</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">删除</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">工序:</span> |
| | | <el-input |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">供应商:</span> |
| | | <el-input |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">事故名称:</span> |
| | | <el-input v-model="searchForm.accidentName" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">应急预案名称:</span> |
| | | <el-input v-model="searchForm.planName" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">危险源名称:</span> |
| | | <el-input v-model="searchForm.name" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">危险源名称:</span> |
| | | <el-input v-model="searchForm.name" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- 标签页切换不同的审批类型 --> |
| | | <div class="search_form"> |
| | | <div class="search_form mb20"> |
| | | <div> |
| | | <span class="search_title">流程编号:</span> |
| | | <el-input v-model="searchForm.approveId" |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div class="search_form" style="margin-bottom: 20px;"> |
| | | <div> |
| | | <span class="search_title">客户名称:</span> |
| | | <el-input |
| | |
| | | const { VITE_APP_ENV } = env; |
| | | const baseUrl = |
| | | env.VITE_APP_ENV === "development" |
| | | ? "http://localhost:7005" |
| | | ? "http://1.15.17.182:9003" |
| | | : env.VITE_BASE_API; |
| | | const javaUrl = |
| | | env.VITE_APP_ENV === "development" |