Merge branch 'dev_NEW_pro' of http://114.132.189.42:9002/r/product-inventory-management into dev_NEW_pro
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | /** éè´å
¥åºå页å表 */ |
| | | export const listPageAccountPurchase = (params) => { |
| | | return request({ |
| | | url: "/accountPurchase/listPageAccountPurchase", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | /** éè´éè´§å页å表 */ |
| | | export const listPageAccountPurchaseReturn = (params) => { |
| | | return request({ |
| | | url: "/accountPurchase/listPageAccountPurchaseReturn", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | /** éå®åºåºå页å表 */ |
| | | export const listPageAccountSales = (params) => { |
| | | return request({ |
| | | url: "/accountSales/listPageAccountSales", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | /** éå®éè´§å页å表 */ |
| | | export const listPageAccountSalesReturn = (params) => { |
| | | return request({ |
| | | url: "/accountSales/listPageAccountSalesReturn", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | |
| | | name: "PurchaseIn", |
| | | meta: { title: "éè´å
¥åº" }, |
| | | }, |
| | | |
| | | { |
| | | path: "purchase-return", |
| | | component: () => import("@/views/financialManagement/payable/purchaseReturn.vue"), |
| | | name: "PurchaseReturn", |
| | | meta: { title: "éè´éè´§" }, |
| | | }, |
| | | { |
| | | path: "input-invoice", |
| | | component: () => import("@/views/financialManagement/payable/input-invoice.vue"), |
| | |
| | | <template> |
| | | <!-- éè´å
¥åº --> |
| | | <div class="app-container"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="å
¥åºåå·:"> |
| | | <el-input v-model="filters.inCode" placeholder="请è¾å
¥å
¥åºåå·" clearable style="width: 200px;" /> |
| | | <el-input v-model="filters.inboundBatches" placeholder="请è¾å
¥å
¥åºåå·" clearable style="width: 200px;" /> |
| | | </el-form-item> |
| | | <el-form-item label="ä¾åºå:"> |
| | | <el-select v-model="filters.supplierId" placeholder="è¯·éæ©ä¾åºå" clearable style="width: 200px;"> |
| | | <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | <el-input v-model="filters.supplierName" placeholder="请è¾å
¥ä¾åºå" clearable style="width: 200px;" /> |
| | | </el-form-item> |
| | | <el-form-item label="å
¥åºæ¥æ:"> |
| | | <el-date-picker v-model="filters.dateRange" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" range-separator="è³" start-placeholder="å¼å§æ¥æ" end-placeholder="ç»ææ¥æ" clearable /> |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">æç´¢</el-button> |
| | | <el-button type="primary" @click="onSearch">æç´¢</el-button> |
| | | <el-button @click="resetFilters">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | |
| | | rowKey="id" |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :tableLoading="tableLoading" |
| | | :page="{ |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | |
| | | }" |
| | | @pagination="changePage" |
| | | > |
| | | <template #amount="{ row }"> |
| | | <span class="text-primary">Â¥{{ formatMoney(row.amount) }}</span> |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <el-tag :type="getStatusType(row.status)">{{ getStatusLabel(row.status) }}</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button type="primary" link @click="view(row)">æ¥ç</el-button> |
| | | <el-button type="primary" link @click="edit(row)" v-if="row.status === 'pending'">ç¼è¾</el-button> |
| | | <el-button type="danger" link @click="handleDelete(row)" v-if="row.status === 'pending'">å é¤</el-button> |
| | | <template #inboundDate="{ row }"> |
| | | {{ row.InboundDate || row.inboundDate || "" }} |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | |
| | | <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 label="å
¥åºåå·" prop="inCode"> |
| | | <el-input v-model="form.inCode" placeholder="请è¾å
¥å
¥åºåå·" :disabled="isEdit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¾åºå" prop="supplierId"> |
| | | <el-select v-model="form.supplierId" placeholder="è¯·éæ©ä¾åºå" style="width: 100%;" :disabled="isEdit"> |
| | | <el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºæ¥æ" prop="inDate"> |
| | | <el-date-picker v-model="form.inDate" type="date" placeholder="éæ©æ¥æ" value-format="YYYY-MM-DD" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºéé¢" prop="amount"> |
| | | <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="å
¥åºæç»" prop="details"> |
| | | <el-table :data="form.details" border style="width: 100%"> |
| | | <el-table-column prop="materialName" label="ç©æåç§°" width="150"> |
| | | <template #default="{ $index }"> |
| | | <el-input v-model="form.details[$index].materialName" placeholder="ç©æåç§°" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="spec" label="è§æ ¼" width="120"> |
| | | <template #default="{ $index }"> |
| | | <el-input v-model="form.details[$index].spec" placeholder="è§æ ¼" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="quantity" label="æ°é" width="100"> |
| | | <template #default="{ $index }"> |
| | | <el-input-number v-model="form.details[$index].quantity" :min="0" style="width: 100%;" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="unitPrice" label="åä»·" width="120"> |
| | | <template #default="{ $index }"> |
| | | <el-input-number v-model="form.details[$index].unitPrice" :min="0" :precision="2" style="width: 100%;" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="total" label="éé¢" width="120"> |
| | | <template #default="{ row }"> |
| | | <span>Â¥{{ formatMoney(row.quantity * row.unitPrice) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="80"> |
| | | <template #default="{ $index }"> |
| | | <el-button type="danger" link @click="removeDetail($index)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-button type="primary" link @click="addDetail" style="margin-top: 10px;">+ æ·»å æç»</el-button> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button type="primary" @click="submitForm">ç¡®å®</el-button> |
| | | <el-button @click="dialogVisible = false">åæ¶</el-button> |
| | | </template> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { ref, reactive, onMounted, getCurrentInstance } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { listPageAccountPurchase } from "@/api/financialManagement/accountPurchase"; |
| | | |
| | | defineOptions({ |
| | | name: "éè´å
¥åº", |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | const filters = reactive({ |
| | | inCode: "", |
| | | supplierId: "", |
| | | inboundBatches: "", |
| | | supplierName: "", |
| | | dateRange: [], |
| | | }); |
| | | |
| | |
| | | }); |
| | | |
| | | const columns = [ |
| | | { label: "å
¥åºåå·", prop: "inCode", width: "150" }, |
| | | { label: "ä¾åºå", prop: "supplierName", width: "180" }, |
| | | { label: "å
¥åºæ¥æ", prop: "inDate", width: "120" }, |
| | | { label: "å
¥åºéé¢", prop: "amount", slot: "amount" }, |
| | | { label: "ç¶æ", prop: "status", slot: "status" }, |
| | | { label: "夿³¨", prop: "remark", showOverflowTooltip: true }, |
| | | { label: "æä½", prop: "operation", slot: "operation", width: "200", fixed: "right" }, |
| | | { label: "å
¥åºåå·", prop: "inboundBatches", minWidth: "150" }, |
| | | { label: "ä¾åºå", prop: "supplierName", minWidth: "180" }, |
| | | { |
| | | label: "å
¥åºæ¥æ", |
| | | prop: "InboundDate", |
| | | minWidth: "170", |
| | | dataType: "slot", |
| | | slot: "inboundDate", |
| | | }, |
| | | { label: "产ååç§°", prop: "productName", minWidth: "140" }, |
| | | { label: "产åè§æ ¼", prop: "specificationModel", minWidth: "140" }, |
| | | { label: "éè´è®¢åå·", prop: "purchaseContractNumber", minWidth: "150" }, |
| | | ]; |
| | | |
| | | const dataList = ref([]); |
| | | const dialogVisible = ref(false); |
| | | const dialogTitle = ref(""); |
| | | const formRef = ref(null); |
| | | const isEdit = ref(false); |
| | | const currentId = ref(null); |
| | | const tableLoading = ref(false); |
| | | |
| | | const supplierList = [ |
| | | { id: 1, name: "åäº¬åææä¾åºå" }, |
| | | { id: 2, name: "䏿µ·çµåå
å¨ä»¶å
¬å¸" }, |
| | | { id: 3, name: "广å·å
è£
ææå" }, |
| | | { id: 4, name: "æ·±å³äºéé
ä»¶å
¬å¸" }, |
| | | ]; |
| | | function buildFilterParams() { |
| | | const params = { |
| | | inboundBatches: filters.inboundBatches || undefined, |
| | | supplierName: filters.supplierName || undefined, |
| | | }; |
| | | if (filters.dateRange && filters.dateRange.length === 2) { |
| | | params.startDate = filters.dateRange[0]; |
| | | params.endDate = filters.dateRange[1]; |
| | | } |
| | | return params; |
| | | } |
| | | |
| | | const form = reactive({ |
| | | inCode: "", |
| | | supplierId: "", |
| | | inDate: "", |
| | | amount: 0, |
| | | details: [], |
| | | remark: "", |
| | | }); |
| | | |
| | | const rules = { |
| | | inCode: [{ required: true, message: "请è¾å
¥å
¥åºåå·", trigger: "blur" }], |
| | | supplierId: [{ required: true, message: "è¯·éæ©ä¾åºå", trigger: "change" }], |
| | | inDate: [{ required: true, message: "è¯·éæ©å
¥åºæ¥æ", trigger: "change" }], |
| | | amount: [{ required: true, message: "请è¾å
¥å
¥åºéé¢", trigger: "blur" }], |
| | | }; |
| | | |
| | | const mockData = [ |
| | | { id: 1, inCode: "RK2024001", supplierId: 1, supplierName: "åäº¬åææä¾åºå", inDate: "2024-01-10", amount: 8000, status: "approved", details: [{ materialName: "颿", spec: "Q235", quantity: 10, unitPrice: 500 }], remark: "" }, |
| | | { id: 2, inCode: "RK2024002", supplierId: 2, supplierName: "䏿µ·çµåå
å¨ä»¶å
¬å¸", inDate: "2024-01-12", amount: 12000, status: "pending", details: [{ materialName: "è¯ç", spec: "STM32", quantity: 100, unitPrice: 80 }], remark: "" }, |
| | | { id: 3, inCode: "RK2024003", supplierId: 3, supplierName: "广å·å
è£
ææå", inDate: "2024-01-15", amount: 3500, status: "approved", details: [{ materialName: "纸箱", spec: "50*40*30", quantity: 500, unitPrice: 5 }], remark: "" }, |
| | | ]; |
| | | |
| | | const formatMoney = (value) => { |
| | | if (value === undefined || value === null) return "0.00"; |
| | | return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ","); |
| | | }; |
| | | |
| | | const getStatusLabel = (status) => { |
| | | const map = { pending: "å¾
å®¡æ ¸", approved: "å·²å®¡æ ¸", rejected: "已驳å" }; |
| | | return map[status] || status; |
| | | }; |
| | | |
| | | const getStatusType = (status) => { |
| | | const map = { pending: "warning", approved: "success", rejected: "danger" }; |
| | | return map[status] || ""; |
| | | const onSearch = () => { |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const getTableData = () => { |
| | | let result = [...mockData]; |
| | | if (filters.inCode) { |
| | | result = result.filter(item => item.inCode.includes(filters.inCode)); |
| | | } |
| | | if (filters.supplierId) { |
| | | result = result.filter(item => item.supplierId === filters.supplierId); |
| | | } |
| | | if (filters.dateRange && filters.dateRange.length === 2) { |
| | | result = result.filter(item => item.inDate >= filters.dateRange[0] && item.inDate <= filters.dateRange[1]); |
| | | } |
| | | pagination.total = result.length; |
| | | dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize); |
| | | tableLoading.value = true; |
| | | listPageAccountPurchase({ |
| | | ...buildFilterParams(), |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | | }) |
| | | .then((res) => { |
| | | const ok = res.code === 200 || res.code === 0; |
| | | if (ok && res.data) { |
| | | pagination.total = res.data.total ?? 0; |
| | | dataList.value = res.data.records ?? []; |
| | | } else { |
| | | ElMessage.error(res.msg || "æ¥è¯¢å¤±è´¥"); |
| | | dataList.value = []; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | dataList.value = []; |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const resetFilters = () => { |
| | | filters.inCode = ""; |
| | | filters.supplierId = ""; |
| | | filters.inboundBatches = ""; |
| | | filters.supplierName = ""; |
| | | filters.dateRange = []; |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const changePage = ({ current, size }) => { |
| | | pagination.currentPage = current; |
| | | pagination.pageSize = size; |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.currentPage = page; |
| | | pagination.pageSize = limit; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const addDetail = () => { |
| | | form.details.push({ materialName: "", spec: "", quantity: 0, unitPrice: 0 }); |
| | | }; |
| | | |
| | | const removeDetail = (index) => { |
| | | form.details.splice(index, 1); |
| | | }; |
| | | |
| | | const add = () => { |
| | | isEdit.value = false; |
| | | dialogTitle.value = "æ°å¢å
¥åº"; |
| | | Object.assign(form, { |
| | | inCode: "RK" + Date.now().toString().slice(-8), |
| | | supplierId: "", |
| | | inDate: new Date().toISOString().split('T')[0], |
| | | amount: 0, |
| | | details: [{ materialName: "", spec: "", quantity: 0, unitPrice: 0 }], |
| | | remark: "", |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const edit = (row) => { |
| | | isEdit.value = true; |
| | | currentId.value = row.id; |
| | | dialogTitle.value = "ç¼è¾å
¥åº"; |
| | | Object.assign(form, row); |
| | | if (!form.details || form.details.length === 0) { |
| | | form.details = [{ materialName: "", spec: "", quantity: 0, unitPrice: 0 }]; |
| | | } |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const view = (row) => { |
| | | ElMessage.info(`æ¥çå
¥åºå: ${row.inCode}`); |
| | | }; |
| | | |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm("确认å é¤è¯¥å
¥åºååï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | const index = mockData.findIndex(item => item.id === row.id); |
| | | if (index !== -1) { |
| | | mockData.splice(index, 1); |
| | | } |
| | | ElMessage.success("å 餿å"); |
| | | getTableData(); |
| | | }); |
| | | }; |
| | | |
| | | const handleOut = () => { |
| | | ElMessage.success("å¯¼åºæå"); |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (valid) { |
| | | const supplier = supplierList.find(item => item.id === form.supplierId); |
| | | if (isEdit.value) { |
| | | const index = mockData.findIndex(item => item.id === currentId.value); |
| | | if (index !== -1) { |
| | | mockData[index] = { ...mockData[index], ...form, supplierName: supplier?.name }; |
| | | } |
| | | ElMessage.success("ç¼è¾æå"); |
| | | } else { |
| | | const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1; |
| | | mockData.push({ id: newId, ...form, supplierName: supplier?.name, status: "pending" }); |
| | | ElMessage.success("æ°å¢æå"); |
| | | } |
| | | dialogVisible.value = false; |
| | | getTableData(); |
| | | } |
| | | }); |
| | | proxy.download( |
| | | "/accountPurchase/exportAccountPurchaseInbound", |
| | | buildFilterParams(), |
| | | `éè´å
¥åº_${new Date().getTime()}.xlsx` |
| | | ); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .text-primary { |
| | | color: #409eff; |
| | | font-weight: bold; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <!-- éè´éè´§ --> |
| | | |
| | | <div class="app-container"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="éè´§åå·:"> |
| | | <el-input |
| | | v-model="filters.returnNo" |
| | | placeholder="请è¾å
¥éè´§åå·" |
| | | clearable |
| | | style="width: 200px" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="ä¾åºå:"> |
| | | <el-input |
| | | v-model="filters.supplierName" |
| | | placeholder="请è¾å
¥ä¾åºå" |
| | | clearable |
| | | style="width: 200px" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="éè´§æ¥æ:"> |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-button type="primary" @click="onSearch">æç´¢</el-button> |
| | | |
| | | <el-button @click="resetFilters">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="table_list"> |
| | | <div class="actions"> |
| | | <div></div> |
| | | |
| | | <div> |
| | | <el-button @click="handleOut" icon="Download">导åº</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :tableLoading="tableLoading" |
| | | :page="{ |
| | | current: pagination.currentPage, |
| | | |
| | | size: pagination.pageSize, |
| | | |
| | | total: pagination.total, |
| | | }" |
| | | @pagination="changePage" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, getCurrentInstance } from "vue"; |
| | | |
| | | import { ElMessage } from "element-plus"; |
| | | |
| | | import { listPageAccountPurchaseReturn } from "@/api/financialManagement/accountPurchase"; |
| | | |
| | | defineOptions({ |
| | | name: "éè´éè´§", |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | const filters = reactive({ |
| | | returnNo: "", |
| | | |
| | | supplierName: "", |
| | | |
| | | dateRange: [], |
| | | }); |
| | | |
| | | const pagination = reactive({ |
| | | currentPage: 1, |
| | | |
| | | pageSize: 10, |
| | | |
| | | total: 0, |
| | | }); |
| | | |
| | | const columns = [ |
| | | { label: "éè´§åå·", prop: "returnNo", minWidth: "150" }, |
| | | |
| | | { label: "ä¾åºå", prop: "supplierName", minWidth: "180" }, |
| | | |
| | | { label: "å
³èå
¥åºåå·", prop: "inboundBatches", minWidth: "150" }, |
| | | |
| | | { label: "éè´§æ¥æ", prop: "preparedAt", minWidth: "170" }, |
| | | |
| | | { |
| | | label: "鿬¾æ»é¢", |
| | | |
| | | prop: "totalAmount", |
| | | |
| | | minWidth: "150", |
| | | |
| | | align: "right", |
| | | |
| | | formatData: (val) => |
| | | val === null || val === undefined || val === "" |
| | | ? "" |
| | | : Number(val).toLocaleString("zh-CN", { |
| | | minimumFractionDigits: 2, |
| | | maximumFractionDigits: 2, |
| | | }), |
| | | }, |
| | | |
| | | { label: "éè´§æ¹å¼", prop: "returnType", minWidth: "150" }, |
| | | |
| | | { label: "éè´è®¢åå·", prop: "purchaseContractNumber", minWidth: "150" }, |
| | | ]; |
| | | |
| | | const dataList = ref([]); |
| | | |
| | | const tableLoading = ref(false); |
| | | |
| | | function buildFilterParams() { |
| | | const params = { |
| | | returnNo: filters.returnNo || undefined, |
| | | |
| | | supplierName: filters.supplierName || undefined, |
| | | }; |
| | | |
| | | if (filters.dateRange && filters.dateRange.length === 2) { |
| | | params.startDate = filters.dateRange[0]; |
| | | |
| | | params.endDate = filters.dateRange[1]; |
| | | } |
| | | |
| | | return params; |
| | | } |
| | | |
| | | const onSearch = () => { |
| | | pagination.currentPage = 1; |
| | | |
| | | getTableData(); |
| | | }; |
| | | |
| | | const getTableData = () => { |
| | | tableLoading.value = true; |
| | | |
| | | listPageAccountPurchaseReturn({ |
| | | ...buildFilterParams(), |
| | | |
| | | current: pagination.currentPage, |
| | | |
| | | size: pagination.pageSize, |
| | | }) |
| | | .then((res) => { |
| | | const ok = res.code === 200 || res.code === 0; |
| | | |
| | | if (ok && res.data) { |
| | | pagination.total = res.data.total ?? 0; |
| | | |
| | | dataList.value = res.data.records ?? []; |
| | | } else { |
| | | ElMessage.error(res.msg || "æ¥è¯¢å¤±è´¥"); |
| | | |
| | | dataList.value = []; |
| | | } |
| | | }) |
| | | |
| | | .catch(() => { |
| | | dataList.value = []; |
| | | }) |
| | | |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const resetFilters = () => { |
| | | filters.returnNo = ""; |
| | | |
| | | filters.supplierName = ""; |
| | | |
| | | filters.dateRange = []; |
| | | |
| | | pagination.currentPage = 1; |
| | | |
| | | getTableData(); |
| | | }; |
| | | |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.currentPage = page; |
| | | |
| | | pagination.pageSize = limit; |
| | | |
| | | getTableData(); |
| | | }; |
| | | |
| | | const handleOut = () => { |
| | | proxy.download( |
| | | "/accountPurchase/exportAccountPurchaseReturn", |
| | | |
| | | buildFilterParams(), |
| | | |
| | | `éè´éè´§_${new Date().getTime()}.xlsx` |
| | | ); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getTableData(); |
| | | }); |
| | | </script> |
| | | |
| | | |
| | | |
| | | <style lang="scss" scoped> |
| | | .actions { |
| | | display: flex; |
| | | |
| | | justify-content: space-between; |
| | | |
| | | margin-bottom: 15px; |
| | | } |
| | | </style> |
| | | |
| | |
| | | <template> |
| | | <!-- éå®åºåº --> |
| | | <div class="app-container"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="åºåºåå·:"> |
| | | <el-input v-model="filters.outCode" placeholder="请è¾å
¥åºåºåå·" clearable style="width: 200px;" /> |
| | | <el-input v-model="filters.outboundBatches" placeholder="请è¾å
¥åºåºåå·" clearable style="width: 200px;" /> |
| | | </el-form-item> |
| | | <el-form-item label="客æ·:"> |
| | | <el-select v-model="filters.customerId" placeholder="è¯·éæ©å®¢æ·" clearable style="width: 200px;"> |
| | | <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | <el-form-item label="客æ·åç§°:"> |
| | | <el-input v-model="filters.customerName" placeholder="请è¾å
¥å®¢æ·åç§°" clearable style="width: 200px;" /> |
| | | </el-form-item> |
| | | <el-form-item label="åºåºæ¥æ:"> |
| | | <el-date-picker v-model="filters.dateRange" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" range-separator="è³" start-placeholder="å¼å§æ¥æ" end-placeholder="ç»ææ¥æ" clearable /> |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">æç´¢</el-button> |
| | | <el-button type="primary" @click="onSearch">æç´¢</el-button> |
| | | <el-button @click="resetFilters">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | |
| | | rowKey="id" |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :tableLoading="tableLoading" |
| | | :page="{ |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | | total: pagination.total, |
| | | }" |
| | | @pagination="changePage" |
| | | > |
| | | <template #status="{ row }"> |
| | | <el-tag :type="getStatusType(row.status)">{{ getStatusLabel(row.status) }}</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button type="primary" link @click="view(row)">æ¥ç</el-button> |
| | | <el-button type="primary" link @click="edit(row)" v-if="row.status === 'pending'">ç¼è¾</el-button> |
| | | <el-button type="danger" link @click="handleDelete(row)" v-if="row.status === 'pending'">å é¤</el-button> |
| | | </template> |
| | | </PIMTable> |
| | | /> |
| | | </div> |
| | | |
| | | <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 label="åºåºåå·" prop="outCode"> |
| | | <el-input v-model="form.outCode" placeholder="请è¾å
¥åºåºåå·" :disabled="isEdit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·" prop="customerId"> |
| | | <el-select v-model="form.customerId" placeholder="è¯·éæ©å®¢æ·" style="width: 100%;" :disabled="isEdit"> |
| | | <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåºæ¥æ" prop="outDate"> |
| | | <el-date-picker v-model="form.outDate" type="date" placeholder="éæ©æ¥æ" value-format="YYYY-MM-DD" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éé¢" prop="amount"> |
| | | <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button type="primary" @click="submitForm">ç¡®å®</el-button> |
| | | <el-button @click="dialogVisible = false">åæ¶</el-button> |
| | | </template> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { ref, reactive, onMounted, getCurrentInstance } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { listPageAccountSales } from "@/api/financialManagement/accountSales"; |
| | | |
| | | defineOptions({ |
| | | name: "éå®åºåº", |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | const filters = reactive({ |
| | | outCode: "", |
| | | customerId: "", |
| | | outboundBatches: "", |
| | | customerName: "", |
| | | dateRange: [], |
| | | }); |
| | | |
| | |
| | | }); |
| | | |
| | | const columns = [ |
| | | { label: "åºåºåå·", prop: "outCode", width: "150" }, |
| | | { label: "客æ·åç§°", prop: "customerName", width: "180" }, |
| | | { label: "åºåºæ¥æ", prop: "outDate", width: "120" }, |
| | | { label: "éé¢", prop: "amount", width: "120" }, |
| | | { label: "ç¶æ", prop: "status", slot: "status" }, |
| | | { label: "夿³¨", prop: "remark", showOverflowTooltip: true }, |
| | | { label: "æä½", prop: "operation", slot: "operation", width: "200", fixed: "right" }, |
| | | { label: "åºåºåå·", prop: "outboundBatches", minWidth: "150" }, |
| | | { label: "客æ·åç§°", prop: "customerName", minWidth: "180" }, |
| | | { label: "åºåºæ¥æ", prop: "shippingDate", width: "170" }, |
| | | { label: "产ååç§°", prop: "productName", minWidth: "140" }, |
| | | { label: "产åè§æ ¼", prop: "specificationModel", minWidth: "140" }, |
| | | { |
| | | label: "éé¢", |
| | | prop: "outboundAmount", |
| | | minWidth: "120", |
| | | align: "right", |
| | | formatData: (val) => (val === null || val === undefined || val === "" ? "" : Number(val).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })), |
| | | }, |
| | | { label: "åè´§ç¼å·", prop: "shippingNo", minWidth: "140" }, |
| | | { label: "éå®è®¢åå·", prop: "salesContractNo", minWidth: "150" }, |
| | | ]; |
| | | |
| | | const dataList = ref([]); |
| | | const dialogVisible = ref(false); |
| | | const dialogTitle = ref(""); |
| | | const formRef = ref(null); |
| | | const isEdit = ref(false); |
| | | const currentId = ref(null); |
| | | const tableLoading = ref(false); |
| | | |
| | | const customerList = [ |
| | | { id: 1, name: "åäº¬ç§ææéå
¬å¸" }, |
| | | { id: 2, name: "䏿µ·è´¸æå
¬å¸" }, |
| | | { id: 3, name: "广å·å®ä¸æéå
¬å¸" }, |
| | | { id: 4, name: "æ·±å³çµåå
¬å¸" }, |
| | | ]; |
| | | function buildFilterParams() { |
| | | const params = { |
| | | outboundBatches: filters.outboundBatches || undefined, |
| | | customerName: filters.customerName || undefined, |
| | | }; |
| | | if (filters.dateRange && filters.dateRange.length === 2) { |
| | | params.startDate = filters.dateRange[0]; |
| | | params.endDate = filters.dateRange[1]; |
| | | } |
| | | return params; |
| | | } |
| | | |
| | | const form = reactive({ |
| | | outCode: "", |
| | | customerId: "", |
| | | outDate: "", |
| | | amount: 0, |
| | | remark: "", |
| | | }); |
| | | |
| | | const rules = { |
| | | outCode: [{ required: true, message: "请è¾å
¥åºåºåå·", trigger: "blur" }], |
| | | customerId: [{ required: true, message: "è¯·éæ©å®¢æ·", trigger: "change" }], |
| | | outDate: [{ required: true, message: "è¯·éæ©åºåºæ¥æ", trigger: "change" }], |
| | | amount: [{ required: true, message: "请è¾å
¥éé¢", trigger: "blur" }], |
| | | }; |
| | | |
| | | const mockData = [ |
| | | { id: 1, outCode: "CK2024001", customerId: 1, customerName: "åäº¬ç§ææéå
¬å¸", outDate: "2024-01-15", amount: 5000, status: "approved", remark: "" }, |
| | | { id: 2, outCode: "CK2024002", customerId: 2, customerName: "䏿µ·è´¸æå
¬å¸", outDate: "2024-01-16", amount: 8000, status: "pending", remark: "" }, |
| | | { id: 3, outCode: "CK2024003", customerId: 3, customerName: "广å·å®ä¸æéå
¬å¸", outDate: "2024-01-18", amount: 12000, status: "approved", remark: "" }, |
| | | { id: 4, outCode: "CK2024004", customerId: 4, customerName: "æ·±å³çµåå
¬å¸", outDate: "2024-01-20", amount: 3500, status: "pending", remark: "" }, |
| | | ]; |
| | | |
| | | const getStatusLabel = (status) => { |
| | | const map = { pending: "å¾
å®¡æ ¸", approved: "å·²å®¡æ ¸", rejected: "已驳å" }; |
| | | return map[status] || status; |
| | | }; |
| | | |
| | | const getStatusType = (status) => { |
| | | const map = { pending: "warning", approved: "success", rejected: "danger" }; |
| | | return map[status] || ""; |
| | | const onSearch = () => { |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const getTableData = () => { |
| | | let result = [...mockData]; |
| | | if (filters.outCode) { |
| | | result = result.filter(item => item.outCode.includes(filters.outCode)); |
| | | } |
| | | if (filters.customerId) { |
| | | result = result.filter(item => item.customerId === filters.customerId); |
| | | } |
| | | if (filters.dateRange && filters.dateRange.length === 2) { |
| | | result = result.filter(item => item.outDate >= filters.dateRange[0] && item.outDate <= filters.dateRange[1]); |
| | | } |
| | | pagination.total = result.length; |
| | | dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize); |
| | | tableLoading.value = true; |
| | | listPageAccountSales({ |
| | | ...buildFilterParams(), |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | | }) |
| | | .then((res) => { |
| | | const ok = res.code === 200 || res.code === 0; |
| | | if (ok && res.data) { |
| | | pagination.total = res.data.total ?? 0; |
| | | dataList.value = res.data.records ?? []; |
| | | } else { |
| | | ElMessage.error(res.msg || "æ¥è¯¢å¤±è´¥"); |
| | | dataList.value = []; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | dataList.value = []; |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const resetFilters = () => { |
| | | filters.outCode = ""; |
| | | filters.customerId = ""; |
| | | filters.outboundBatches = ""; |
| | | filters.customerName = ""; |
| | | filters.dateRange = []; |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const changePage = ({ current, size }) => { |
| | | pagination.currentPage = current; |
| | | pagination.pageSize = size; |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.currentPage = page; |
| | | pagination.pageSize = limit; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const add = () => { |
| | | isEdit.value = false; |
| | | dialogTitle.value = "æ°å¢åºåº"; |
| | | Object.assign(form, { |
| | | outCode: "CK" + Date.now(), |
| | | customerId: "", |
| | | outDate: "", |
| | | amount: 0, |
| | | remark: "", |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const edit = (row) => { |
| | | isEdit.value = true; |
| | | currentId.value = row.id; |
| | | dialogTitle.value = "ç¼è¾åºåº"; |
| | | Object.assign(form, row); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const view = (row) => { |
| | | ElMessage.info(`æ¥çåºåºå: ${row.outCode}`); |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (valid) { |
| | | const customer = customerList.find(item => item.id === form.customerId); |
| | | if (isEdit.value) { |
| | | const index = mockData.findIndex(item => item.id === currentId.value); |
| | | if (index !== -1) { |
| | | mockData[index] = { ...mockData[index], ...form, customerName: customer?.name }; |
| | | } |
| | | ElMessage.success("ç¼è¾æå"); |
| | | } else { |
| | | const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1; |
| | | mockData.push({ id: newId, ...form, customerName: customer?.name, status: "pending" }); |
| | | ElMessage.success("æ°å¢æå"); |
| | | } |
| | | dialogVisible.value = false; |
| | | getTableData(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm("确认å é¤è¯¥åºåºååï¼", "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }).then(() => { |
| | | const index = mockData.findIndex(item => item.id === row.id); |
| | | if (index !== -1) { |
| | | mockData.splice(index, 1); |
| | | } |
| | | ElMessage.success("å 餿å"); |
| | | getTableData(); |
| | | }); |
| | | }; |
| | | |
| | | const handleOut = () => { |
| | | ElMessage.success("å¯¼åºæå"); |
| | | proxy.download( |
| | | "/accountSales/exportAccountSalesOutbound", |
| | | buildFilterParams(), |
| | | `éå®åºåº_${new Date().getTime()}.xlsx` |
| | | ); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | |
| | | <template> |
| | | <!-- éå®éè´§ --> |
| | | <div class="app-container"> |
| | | <el-form :model="filters" :inline="true"> |
| | | <el-form-item label="éè´§åå·:"> |
| | | <el-input v-model="filters.returnCode" placeholder="请è¾å
¥éè´§åå·" clearable style="width: 200px;" /> |
| | | <el-input v-model="filters.returnNo" placeholder="请è¾å
¥éè´§åå·" clearable style="width: 200px;" /> |
| | | </el-form-item> |
| | | <el-form-item label="客æ·:"> |
| | | <el-select v-model="filters.customerId" placeholder="è¯·éæ©å®¢æ·" clearable style="width: 200px;"> |
| | | <el-option v-for="item in customerList" :key="item.id" :label="item.name" :value="item.id" /> |
| | | </el-select> |
| | | <el-form-item label="客æ·åç§°:"> |
| | | <el-input v-model="filters.customerName" placeholder="请è¾å
¥å®¢æ·åç§°" clearable style="width: 200px;" /> |
| | | </el-form-item> |
| | | <el-form-item label="éè´§æ¥æ:"> |
| | | <el-date-picker v-model="filters.dateRange" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" range-separator="è³" start-placeholder="å¼å§æ¥æ" end-placeholder="ç»ææ¥æ" clearable /> |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="getTableData">æç´¢</el-button> |
| | | <el-button type="primary" @click="onSearch">æç´¢</el-button> |
| | | <el-button @click="resetFilters">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | |
| | | rowKey="id" |
| | | :column="columns" |
| | | :tableData="dataList" |
| | | :tableLoading="tableLoading" |
| | | :page="{ |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | | total: pagination.total, |
| | | }" |
| | | @pagination="changePage" |
| | | > |
| | | <template #status="{ row }"> |
| | | <el-tag :type="getStatusType(row.status)">{{ getStatusLabel(row.status) }}</el-tag> |
| | | </template> |
| | | <template #operation="{ row }"> |
| | | <el-button type="primary" link @click="view(row)">æ¥ç</el-button> |
| | | <el-button type="primary" link @click="edit(row)" v-if="row.status === 'pending'">ç¼è¾</el-button> |
| | | <el-button type="success" link @click="handleAudit(row)" v-if="row.status === 'pending'">å®¡æ ¸</el-button> |
| | | </template> |
| | | </PIMTable> |
| | | /> |
| | | </div> |
| | | |
| | | <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 label="éè´§åå·" prop="returnCode"> |
| | | <el-input v-model="form.returnCode" placeholder="请è¾å
¥éè´§åå·" :disabled="isEdit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
³èåºåºå" prop="outCode"> |
| | | <el-select v-model="form.outCode" placeholder="è¯·éæ©åºåºå" style="width: 100%;" :disabled="isEdit"> |
| | | <el-option v-for="item in outList" :key="item.outCode" :label="item.outCode" :value="item.outCode" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·" prop="customerId"> |
| | | <el-select v-model="form.customerId" placeholder="è¯·éæ©å®¢æ·" style="width: 100%;" :disabled="isEdit"> |
| | | <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="returnDate"> |
| | | <el-date-picker v-model="form.returnDate" type="date" placeholder="éæ©æ¥æ" value-format="YYYY-MM-DD" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´§éé¢" prop="amount"> |
| | | <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´§åå " prop="reason"> |
| | | <el-input v-model="form.reason" placeholder="请è¾å
¥éè´§åå " /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button type="primary" @click="submitForm">ç¡®å®</el-button> |
| | | <el-button @click="dialogVisible = false">åæ¶</el-button> |
| | | </template> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { ref, reactive, onMounted, getCurrentInstance } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { listPageAccountSalesReturn } from "@/api/financialManagement/accountSales"; |
| | | |
| | | defineOptions({ |
| | | name: "éå®éè´§", |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | const filters = reactive({ |
| | | returnCode: "", |
| | | customerId: "", |
| | | returnNo: "", |
| | | customerName: "", |
| | | dateRange: [], |
| | | }); |
| | | |
| | |
| | | }); |
| | | |
| | | const columns = [ |
| | | { label: "éè´§åå·", prop: "returnCode", width: "150" }, |
| | | { label: "客æ·åç§°", prop: "customerName", width: "180" }, |
| | | { label: "å
³èåºåºå", prop: "outCode", width: "150" }, |
| | | { label: "éè´§æ¥æ", prop: "returnDate", width: "120" }, |
| | | { label: "éè´§éé¢", prop: "amount", width: "120" }, |
| | | { label: "éè´§åå ", prop: "reason", width: "150", showOverflowTooltip: true }, |
| | | { label: "ç¶æ", prop: "status", slot: "status" }, |
| | | { label: "æä½", prop: "operation", slot: "operation", width: "200", fixed: "right" }, |
| | | { label: "éè´§åå·", prop: "returnNo", minWidth: "150" }, |
| | | { label: "客æ·åç§°", prop: "customerName", minWidth: "180" }, |
| | | { label: "å
³èåè´§åå·", prop: "shippingNo", minWidth: "150" }, |
| | | { label: "éè´§æ¥æ", prop: "makeTime", minWidth: "170" }, |
| | | { |
| | | label: "鿬¾æ»é¢", |
| | | prop: "refundAmount", |
| | | minWidth: "120", |
| | | align: "right", |
| | | formatData: (val) => |
| | | val === null || val === undefined || val === "" |
| | | ? "" |
| | | : Number(val).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 }), |
| | | }, |
| | | { label: "éè´§åå ", prop: "returnReason", minWidth: "150", showOverflowTooltip: true }, |
| | | { label: "éå®è®¢åå·", prop: "salesContractNo", minWidth: "150" }, |
| | | ]; |
| | | |
| | | const dataList = ref([]); |
| | | const dialogVisible = ref(false); |
| | | const dialogTitle = ref(""); |
| | | const formRef = ref(null); |
| | | const isEdit = ref(false); |
| | | const currentId = ref(null); |
| | | const tableLoading = ref(false); |
| | | |
| | | const customerList = [ |
| | | { id: 1, name: "åäº¬ç§ææéå
¬å¸" }, |
| | | { id: 2, name: "䏿µ·è´¸æå
¬å¸" }, |
| | | { id: 3, name: "广å·å®ä¸æéå
¬å¸" }, |
| | | { id: 4, name: "æ·±å³çµåå
¬å¸" }, |
| | | ]; |
| | | function buildFilterParams() { |
| | | const params = { |
| | | returnNo: filters.returnNo || undefined, |
| | | customerName: filters.customerName || undefined, |
| | | }; |
| | | if (filters.dateRange && filters.dateRange.length === 2) { |
| | | params.startDate = filters.dateRange[0]; |
| | | params.endDate = filters.dateRange[1]; |
| | | } |
| | | return params; |
| | | } |
| | | |
| | | const outList = [ |
| | | { outCode: "CK2024001", customerId: 1 }, |
| | | { outCode: "CK2024002", customerId: 2 }, |
| | | { outCode: "CK2024003", customerId: 3 }, |
| | | ]; |
| | | |
| | | const form = reactive({ |
| | | returnCode: "", |
| | | outCode: "", |
| | | customerId: "", |
| | | returnDate: "", |
| | | amount: 0, |
| | | reason: "", |
| | | remark: "", |
| | | }); |
| | | |
| | | const rules = { |
| | | returnCode: [{ required: true, message: "请è¾å
¥éè´§åå·", trigger: "blur" }], |
| | | outCode: [{ required: true, message: "è¯·éæ©å
³èåºåºå", trigger: "change" }], |
| | | customerId: [{ required: true, message: "è¯·éæ©å®¢æ·", trigger: "change" }], |
| | | returnDate: [{ required: true, message: "è¯·éæ©éè´§æ¥æ", trigger: "change" }], |
| | | amount: [{ required: true, message: "请è¾å
¥éè´§éé¢", trigger: "blur" }], |
| | | }; |
| | | |
| | | const mockData = [ |
| | | { id: 1, returnCode: "TH2024001", outCode: "CK2024001", customerId: 1, customerName: "åäº¬ç§ææéå
¬å¸", returnDate: "2024-01-20", amount: 1000, reason: "è´¨éé®é¢", status: "approved", remark: "" }, |
| | | { id: 2, returnCode: "TH2024002", outCode: "CK2024002", customerId: 2, customerName: "䏿µ·è´¸æå
¬å¸", returnDate: "2024-01-22", amount: 500, reason: "è§æ ¼ä¸ç¬¦", status: "pending", remark: "" }, |
| | | ]; |
| | | |
| | | const getStatusLabel = (status) => { |
| | | const map = { pending: "å¾
å®¡æ ¸", approved: "å·²å®¡æ ¸", rejected: "已驳å" }; |
| | | return map[status] || status; |
| | | }; |
| | | |
| | | const getStatusType = (status) => { |
| | | const map = { pending: "warning", approved: "success", rejected: "danger" }; |
| | | return map[status] || ""; |
| | | const onSearch = () => { |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const getTableData = () => { |
| | | let result = [...mockData]; |
| | | if (filters.returnCode) { |
| | | result = result.filter(item => item.returnCode.includes(filters.returnCode)); |
| | | } |
| | | if (filters.customerId) { |
| | | result = result.filter(item => item.customerId === filters.customerId); |
| | | } |
| | | if (filters.dateRange && filters.dateRange.length === 2) { |
| | | result = result.filter(item => item.returnDate >= filters.dateRange[0] && item.returnDate <= filters.dateRange[1]); |
| | | } |
| | | pagination.total = result.length; |
| | | dataList.value = result.slice((pagination.currentPage - 1) * pagination.pageSize, pagination.currentPage * pagination.pageSize); |
| | | tableLoading.value = true; |
| | | listPageAccountSalesReturn({ |
| | | ...buildFilterParams(), |
| | | current: pagination.currentPage, |
| | | size: pagination.pageSize, |
| | | }) |
| | | .then((res) => { |
| | | const ok = res.code === 200 || res.code === 0; |
| | | if (ok && res.data) { |
| | | pagination.total = res.data.total ?? 0; |
| | | dataList.value = res.data.records ?? []; |
| | | } else { |
| | | ElMessage.error(res.msg || "æ¥è¯¢å¤±è´¥"); |
| | | dataList.value = []; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | dataList.value = []; |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const resetFilters = () => { |
| | | filters.returnCode = ""; |
| | | filters.customerId = ""; |
| | | filters.returnNo = ""; |
| | | filters.customerName = ""; |
| | | filters.dateRange = []; |
| | | pagination.currentPage = 1; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const changePage = ({ current, size }) => { |
| | | pagination.currentPage = current; |
| | | pagination.pageSize = size; |
| | | const changePage = ({ page, limit }) => { |
| | | pagination.currentPage = page; |
| | | pagination.pageSize = limit; |
| | | getTableData(); |
| | | }; |
| | | |
| | | const add = () => { |
| | | isEdit.value = false; |
| | | dialogTitle.value = "æ°å¢éè´§"; |
| | | Object.assign(form, { |
| | | returnCode: "TH" + Date.now(), |
| | | outCode: "", |
| | | customerId: "", |
| | | returnDate: "", |
| | | amount: 0, |
| | | reason: "", |
| | | remark: "", |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const edit = (row) => { |
| | | isEdit.value = true; |
| | | currentId.value = row.id; |
| | | dialogTitle.value = "ç¼è¾éè´§"; |
| | | Object.assign(form, row); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | const view = (row) => { |
| | | ElMessage.info(`æ¥çéè´§å: ${row.returnCode}`); |
| | | }; |
| | | |
| | | const handleAudit = (row) => { |
| | | ElMessageBox.confirm("ç¡®è®¤å®¡æ ¸éè¿è¯¥éè´§ååï¼", "æç¤º", { |
| | | confirmButtonText: "éè¿", |
| | | cancelButtonText: "驳å", |
| | | distinguishCancelAndClose: true, |
| | | type: "warning", |
| | | }).then(() => { |
| | | const index = mockData.findIndex(item => item.id === row.id); |
| | | if (index !== -1) { |
| | | mockData[index].status = "approved"; |
| | | } |
| | | ElMessage.success("å®¡æ ¸éè¿"); |
| | | getTableData(); |
| | | }).catch((action) => { |
| | | if (action === "cancel") { |
| | | const index = mockData.findIndex(item => item.id === row.id); |
| | | if (index !== -1) { |
| | | mockData[index].status = "rejected"; |
| | | } |
| | | ElMessage.warning("已驳å"); |
| | | getTableData(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | formRef.value.validate((valid) => { |
| | | if (valid) { |
| | | const customer = customerList.find(item => item.id === form.customerId); |
| | | if (isEdit.value) { |
| | | const index = mockData.findIndex(item => item.id === currentId.value); |
| | | if (index !== -1) { |
| | | mockData[index] = { ...mockData[index], ...form, customerName: customer?.name }; |
| | | } |
| | | ElMessage.success("ç¼è¾æå"); |
| | | } else { |
| | | const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1; |
| | | mockData.push({ id: newId, ...form, customerName: customer?.name, status: "pending" }); |
| | | ElMessage.success("æ°å¢æå"); |
| | | } |
| | | dialogVisible.value = false; |
| | | getTableData(); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const handleOut = () => { |
| | | ElMessage.success("å¯¼åºæå"); |
| | | proxy.download( |
| | | "/accountSales/exportAccountSalesReturn", |
| | | buildFilterParams(), |
| | | `éå®éè´§_${new Date().getTime()}.xlsx` |
| | | ); |
| | | }; |
| | | |
| | | onMounted(() => { |