feat: 对账按日、薪资明细与合同/检验列表调整
- 应收/应付对账支持按日对账:筛选改为日期区间,生成对账单可选单日,列表与明细展示具体日期
- 人员薪资列表新增“查看明细”,按人展示基本工资、社保公积金、个税、应发/实发
- 合同管理列表移除紧急联系人、紧急联系人电话、专业列
- 原材料检验列表去掉重复的“检测单位”列
Co-Authored-By: Claude Code <noreply@anthropic.com>
| | |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="对账期间:"> |
| | | <el-date-picker v-model="filters.startMonth" type="month" placeholder="开始月份" value-format="YYYY-MM" style="width: 140px;" /> |
| | | <span style="margin: 0 10px;">至</span> |
| | | <el-date-picker v-model="filters.endMonth" type="month" placeholder="结束月份" value-format="YYYY-MM" style="width: 140px;" /> |
| | | <el-form-item label="对账日期:"> |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | type="daterange" |
| | | placeholder="请选择对账日期" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | range-separator="至" |
| | | clearable |
| | | style="width: 300px;" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="onSearch">搜索</el-button> |
| | |
| | | <FormDialog title="对账明细" v-model="detailDialogVisible" width="900px" @confirm="printDetail" @cancel="detailDialogVisible = false" operationType="detail"> |
| | | <div class="statement-header"> |
| | | <h3>{{ currentSupplier }} 应付对账单</h3> |
| | | <p>对账期间: {{ currentPeriod }}</p> |
| | | <p>对账日期: {{ currentPeriod }}</p> |
| | | </div> |
| | | <el-table :data="detailData" border style="width: 100%" v-loading="detailLoading"> |
| | | <el-table-column prop="date" label="日期" width="120" /> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="对账月份" prop="statementMonth"> |
| | | <el-form-item label="对账日期" prop="statementMonth"> |
| | | <el-date-picker |
| | | v-model="generateForm.statementMonth" |
| | | type="month" |
| | | placeholder="选择月份" |
| | | value-format="YYYY-MM" |
| | | type="date" |
| | | placeholder="选择对账日期" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | style="width: 100%;" |
| | | @change="onStatementMonthChange" |
| | | /> |
| | |
| | | </el-form> |
| | | |
| | | <div v-if="statementDetailLoaded" class="purchase-section"> |
| | | <div v-if="purchaseData.length > 0" class="section-title">本月采购数据</div> |
| | | <div v-if="purchaseData.length > 0" class="section-title">对账日期采购数据</div> |
| | | <el-table |
| | | v-if="purchaseData.length > 0" |
| | | ref="purchaseTableRef" |
| | |
| | | </el-table-column> |
| | | <el-table-column prop="remark" label="备注" /> |
| | | </el-table> |
| | | <el-empty v-else description="该供应商本月暂无明细数据" :image-size="80" /> |
| | | <el-empty v-else description="该供应商当日暂无明细数据" :image-size="80" /> |
| | | |
| | | <div class="summary-row"> |
| | | <span>期初余额: <strong class="text-primary">¥{{ formatMoney(generateForm.openingBalance) }}</strong></span> |
| | |
| | | </div> |
| | | |
| | | <div v-else-if="generateForm.supplierId && generateForm.statementMonth && !purchaseLoading" class="empty-tip"> |
| | | <el-empty description="该供应商本月暂无采购数据" /> |
| | | <el-empty description="该供应商当日暂无采购数据" /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | |
| | | |
| | | const filters = reactive({ |
| | | supplierId: "", |
| | | startMonth: "", |
| | | endMonth: "", |
| | | dateRange: [], |
| | | }); |
| | | |
| | | const pagination = reactive({ |
| | |
| | | const columns = [ |
| | | { label: "对账单号", prop: "statementNumber", width: "150" }, |
| | | { label: "供应商", prop: "supplierName", width: "180" }, |
| | | { label: "对账期间", prop: "statementMonth", width: "150" }, |
| | | { label: "对账日期", prop: "statementMonth", width: "150" }, |
| | | { label: "期初余额", prop: "openingBalance", dataType: "slot", slot: "openingBalance" }, |
| | | { label: "本期应付", prop: "currentPlan", dataType: "slot", slot: "currentPlan" }, |
| | | { label: "本期付款", prop: "currentActually", dataType: "slot", slot: "currentActually" }, |
| | |
| | | if (filters.supplierId) { |
| | | result.customerId = filters.supplierId; |
| | | } |
| | | if (filters.startMonth && filters.endMonth && filters.startMonth === filters.endMonth) { |
| | | result.statementMonth = filters.startMonth; |
| | | } else if (filters.startMonth) { |
| | | result.startMonth = filters.startMonth; |
| | | } |
| | | if (filters.endMonth && filters.startMonth !== filters.endMonth) { |
| | | result.endMonth = filters.endMonth; |
| | | if (Array.isArray(filters.dateRange) && filters.dateRange.length === 2) { |
| | | result.startDate = filters.dateRange[0]; |
| | | result.endDate = filters.dateRange[1]; |
| | | } |
| | | return result; |
| | | }; |
| | |
| | | |
| | | const resetFilters = () => { |
| | | filters.supplierId = ""; |
| | | filters.startMonth = ""; |
| | | filters.endMonth = ""; |
| | | filters.dateRange = []; |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | | }; |
| | |
| | | const viewDetail = (row) => { |
| | | const partnerId = row.customerId ?? row.supplierId; |
| | | if (!partnerId || !row.statementMonth) { |
| | | ElMessage.warning("缺少供应商或对账月份,无法查询明细"); |
| | | ElMessage.warning("缺少供应商或对账日期,无法查询明细"); |
| | | return; |
| | | } |
| | | |
| | |
| | | <el-option v-for="item in customerList" :key="item.id" :label="item.customerName" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="对账期间:"> |
| | | <el-date-picker v-model="filters.startMonth" type="month" placeholder="开始月份" value-format="YYYY-MM" style="width: 140px;" /> |
| | | <span style="margin: 0 10px;">至</span> |
| | | <el-date-picker v-model="filters.endMonth" type="month" placeholder="结束月份" value-format="YYYY-MM" style="width: 140px;" /> |
| | | <el-form-item label="对账日期:"> |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | type="daterange" |
| | | placeholder="请选择对账日期" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | range-separator="至" |
| | | clearable |
| | | style="width: 300px;" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">搜索</el-button> |
| | |
| | | <FormDialog title="对账明细" v-model="detailDialogVisible" width="900px" @confirm="printDetail" @cancel="detailDialogVisible = false" operationType="detail"> |
| | | <div class="statement-header"> |
| | | <h3>{{ currentCustomer }} 应收对账单</h3> |
| | | <p>对账期间: {{ currentPeriod }}</p> |
| | | <p>对账日期: {{ currentPeriod }}</p> |
| | | </div> |
| | | <el-table :data="detailData" border style="width: 100%" v-loading="detailLoading"> |
| | | <el-table-column prop="date" label="日期" width="120" /> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="对账月份" prop="statementMonth"> |
| | | <el-date-picker v-model="generateForm.statementMonth" type="month" placeholder="选择月份" value-format="YYYY-MM" style="width: 100%;" @change="onStatementMonthChange" /> |
| | | <el-form-item label="对账日期" prop="statementMonth"> |
| | | <el-date-picker v-model="generateForm.statementMonth" type="date" placeholder="选择对账日期" value-format="YYYY-MM-DD" format="YYYY-MM-DD" style="width: 100%;" @change="onStatementMonthChange" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <div v-if="statementDetailLoaded" class="sales-section"> |
| | | <div v-if="salesData.length > 0" class="section-title">本月销售数据</div> |
| | | <div v-if="salesData.length > 0" class="section-title">对账日期销售数据</div> |
| | | <el-table |
| | | v-if="salesData.length > 0" |
| | | ref="salesTableRef" |
| | |
| | | </el-table-column> |
| | | <el-table-column prop="remark" label="备注" /> |
| | | </el-table> |
| | | <el-empty v-else description="该客户本月暂无明细数据" :image-size="80" /> |
| | | <el-empty v-else description="该客户当日暂无明细数据" :image-size="80" /> |
| | | |
| | | <div class="summary-row"> |
| | | <span>期初余额: <strong class="text-primary">¥{{ formatMoney(generateForm.openingBalance) }}</strong></span> |
| | |
| | | </div> |
| | | |
| | | <div v-else-if="generateForm.customerId && generateForm.statementMonth && !salesLoading" class="empty-tip"> |
| | | <el-empty description="该客户本月暂无销售数据" /> |
| | | <el-empty description="该客户当日暂无销售数据" /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | |
| | | |
| | | const filters = reactive({ |
| | | customerId: "", |
| | | startMonth: "", |
| | | endMonth: "", |
| | | dateRange: [], |
| | | }); |
| | | |
| | | const pagination = reactive({ |
| | |
| | | const columns = [ |
| | | { label: "对账单号", prop: "statementNumber", width: "150" }, |
| | | { label: "客户名称", prop: "customerName", width: "180" }, |
| | | { label: "对账期间", prop: "statementMonth", width: "150" }, |
| | | { label: "对账日期", prop: "statementMonth", width: "150" }, |
| | | { label: "期初余额", prop: "openingBalance", dataType: "slot", slot: "openingBalance" }, |
| | | { label: "本期应收", prop: "currentPlan", dataType: "slot", slot: "currentPlan" }, |
| | | { label: "本期收款", prop: "currentActually", dataType: "slot", slot: "currentActually" }, |
| | |
| | | if (filters.customerId) { |
| | | result.customerId = filters.customerId; |
| | | } |
| | | if (filters.startMonth && filters.endMonth && filters.startMonth === filters.endMonth) { |
| | | result.statementMonth = filters.startMonth; |
| | | } else if (filters.startMonth) { |
| | | result.startMonth = filters.startMonth; |
| | | } |
| | | if (filters.endMonth && filters.startMonth !== filters.endMonth) { |
| | | result.endMonth = filters.endMonth; |
| | | if (Array.isArray(filters.dateRange) && filters.dateRange.length === 2) { |
| | | result.startDate = filters.dateRange[0]; |
| | | result.endDate = filters.dateRange[1]; |
| | | } |
| | | return result; |
| | | }; |
| | |
| | | |
| | | const resetFilters = () => { |
| | | filters.customerId = ""; |
| | | filters.startMonth = ""; |
| | | filters.endMonth = ""; |
| | | filters.dateRange = []; |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | | }; |
| | |
| | | |
| | | const viewDetail = (row) => { |
| | | if (!row.customerId || !row.statementMonth) { |
| | | ElMessage.warning("缺少客户或对账月份,无法查询明细"); |
| | | ElMessage.warning("缺少客户或对账日期,无法查询明细"); |
| | | return; |
| | | } |
| | | |
| | |
| | | prop: "firstStudy", |
| | | }, |
| | | { |
| | | label: "专业", |
| | | prop: "profession", |
| | | width: 100, |
| | | }, |
| | | { |
| | | label: "年龄", |
| | | prop: "age", |
| | | }, |
| | | { |
| | | label: "联系电话", |
| | | prop: "phone", |
| | | width: 150, |
| | | }, |
| | | { |
| | | label: "紧急联系人", |
| | | prop: "emergencyContact", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "紧急联系人电话", |
| | | prop: "emergencyContactPhone", |
| | | width: 150, |
| | | }, |
| | | // { |
| | |
| | | @close="auditDialogVisible = false" |
| | | @success="handleAuditSuccess" |
| | | /> |
| | | <el-dialog v-model="salaryDetailVisible" title="人员工资明细" width="1100px"> |
| | | <div class="salary-detail-title"> |
| | | {{ salaryDetailRow.salaryTitle || "-" }}({{ salaryDetailRow.salaryMonth || "-" }}) |
| | | </div> |
| | | <el-table :data="salaryDetailRow.staffSalaryDetailList || []" border style="width: 100%"> |
| | | <el-table-column prop="staffName" label="姓名" width="90" /> |
| | | <el-table-column prop="deptName" label="部门" width="110" /> |
| | | <el-table-column prop="postName" label="岗位" width="110" /> |
| | | <el-table-column prop="basicSalary" label="基本工资" width="100" align="right" /> |
| | | <el-table-column prop="pieceSalary" label="计件工资" width="100" align="right" /> |
| | | <el-table-column prop="otherIncome" label="其他收入" width="100" align="right" /> |
| | | <el-table-column prop="socialPersonal" label="社保(个人)" width="100" align="right" /> |
| | | <el-table-column prop="fundPersonal" label="公积金(个人)" width="110" align="right" /> |
| | | <el-table-column prop="salaryTax" label="个税" width="90" align="right" /> |
| | | <el-table-column prop="grossSalary" label="应发工资" width="110" align="right"> |
| | | <template #default="{ row }">{{ formatMoney(row.grossSalary) }}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="deductSalary" label="扣款合计" width="100" align="right" /> |
| | | <el-table-column prop="netSalary" label="实发工资" width="110" align="right"> |
| | | <template #default="{ row }">{{ formatMoney(row.netSalary) }}</template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <template #footer> |
| | | <el-button @click="salaryDetailVisible = false">关闭</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | width: 180, |
| | | operation: [ |
| | | { |
| | | name: "查看明细", |
| | | type: "text", |
| | | clickFun: (row) => openSalaryDetail(row), |
| | | }, |
| | | { |
| | | name: "编辑", |
| | | type: "text", |
| | | disabled: (row) => Number(row?.status) !== 1 && Number(row?.status) !== 2, |
| | |
| | | const auditDialogVisible = ref(false); |
| | | const auditRow = ref(null); |
| | | const auditDiaRef = ref(null); |
| | | const salaryDetailVisible = ref(false); |
| | | const salaryDetailRow = ref({}); |
| | | |
| | | const formatMoney = (value) => { |
| | | if (value === undefined || value === null || value === "") return "-"; |
| | | return Number(value).toFixed(2); |
| | | }; |
| | | |
| | | const openSalaryDetail = (row) => { |
| | | salaryDetailRow.value = row || {}; |
| | | salaryDetailVisible.value = true; |
| | | }; |
| | | |
| | | const issueBankOptions = computed(() => { |
| | | const options = Array.isArray(bankSetting.value?.options) ? bankSetting.value.options : []; |
| | |
| | | .table_list { |
| | | margin-top: 20px; |
| | | } |
| | | .salary-detail-title { |
| | | margin-bottom: 12px; |
| | | font-weight: 600; |
| | | } |
| | | </style> |
| | |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "检测单位", |
| | | prop: "checkCompany", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: "检测结果", |
| | | prop: "checkResult", |
| | | dataType: "tag", |