| | |
| | | @echo off
|
| | | echo.
|
| | | echo [ä¿¡æ¯] æå
Webå·¥ç¨ï¼çædistæä»¶ã
|
| | | echo [��Ϣ] ���Web���̣�����dist�ļ��� |
| | | echo.
|
| | |
|
| | | %~d0
|
| | |
| | | data: query, |
| | | }) |
| | | } |
| | | |
| | | // 临æå®å管ç-å页æ¥è¯¢ |
| | | export function expiryAfterSalesListPage(query) { |
| | | return request({ |
| | | url: '/expiryAfterSales/listPage', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // 临æå®å管ç-æ°å¢ |
| | | export function expiryAfterSalesAdd(query) { |
| | | return request({ |
| | | url: '/expiryAfterSales/add', |
| | | method: 'post', |
| | | data: query, |
| | | }) |
| | | } |
| | | |
| | | // 临æå®å管ç-æ´æ° |
| | | export function expiryAfterSalesUpdate(query) { |
| | | return request({ |
| | | url: '/expiryAfterSales/update', |
| | | method: 'post', |
| | | data: query, |
| | | }) |
| | | } |
| | | |
| | | // 临æå®å管ç-å é¤ |
| | | export function expiryAfterSalesDelete(query) { |
| | | return request({ |
| | | url: '/expiryAfterSales/delete', |
| | | method: 'delete', |
| | | data: query, |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ä¸´æéåå°è´¦å表 |
| | | export function nearExpiryReturnListPage(query) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/listPage', |
| | | method: 'get', |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢ä¸´æéåå°è´¦ |
| | | export function nearExpiryReturnAdd(data) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/add', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹ä¸´æéåå°è´¦ |
| | | export function nearExpiryReturnUpdate(data) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/update', |
| | | method: 'post', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | // å é¤ä¸´æéåå°è´¦ |
| | | export function nearExpiryReturnDel(ids) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/del', |
| | | method: 'delete', |
| | | data: ids, |
| | | }) |
| | | } |
| | | |
| | | // è·å临æéåå°è´¦è¯¦æ
|
| | | export function nearExpiryReturnDetail(id) { |
| | | return request({ |
| | | url: '/quality/nearExpiryReturn/' + id, |
| | | method: 'get', |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | :title="dialogTitle" |
| | | width="70%" |
| | | @close="closeDia" |
| | | > |
| | | <el-form |
| | | :model="form" |
| | | label-width="140px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef" |
| | | > |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="临æäº§ååç§°ï¼" prop="productName"> |
| | | <el-input |
| | | v-model="form.productName" |
| | | placeholder="请è¾å
¥äº§ååç§°" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="äº§åæ¹å·ï¼" prop="batchNumber"> |
| | | <el-input |
| | | v-model="form.batchNumber" |
| | | placeholder="请è¾å
¥äº§åæ¹å·" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¸´ææ¥æï¼" prop="expiryDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.expiryDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©ä¸´ææ¥æ" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåæ°éï¼" prop="stockQuantity"> |
| | | <el-input-number |
| | | v-model="form.stockQuantity" |
| | | :min="0" |
| | | placeholder="请è¾å
¥åºåæ°é" |
| | | style="width: 100%" |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客æ·åç§°ï¼" prop="customerName"> |
| | | <el-input |
| | | v-model="form.customerName" |
| | | placeholder="请è¾å
¥å®¢æ·åç§°" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯ï¼" prop="contactPhone"> |
| | | <el-input |
| | | v-model="form.contactPhone" |
| | | placeholder="请è¾å
¥èç³»çµè¯" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="é®é¢æè¿°ï¼" prop="problemDesc"> |
| | | <el-input |
| | | v-model="form.problemDesc" |
| | | placeholder="请è¾å
¥é®é¢æè¿°" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | type="textarea" |
| | | :rows="3" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30" v-if="operationType !== 'add'"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¤ç人ï¼" prop="handlerId"> |
| | | <el-select |
| | | v-model="form.handlerId" |
| | | placeholder="è¯·éæ©å¤ç人" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.userId" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¤çæ¥æï¼" prop="handleDate"> |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="form.handleDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©å¤çæ¥æ" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30" v-if="operationType !== 'add'"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¤çç»æï¼" prop="handleResult"> |
| | | <el-input |
| | | v-model="form.handleResult" |
| | | placeholder="请è¾å
¥å¤çç»æ" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | type="textarea" |
| | | :rows="3" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm" v-if="operationType !== 'view'">确认</el-button> |
| | | <el-button @click="closeDia">{{ operationType === 'view' ? 'å
³é' : 'åæ¶' }}</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed} from "vue"; |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | // import {userListNoPageByTenantId} from "@/api/system/user.js"; // ææ¶æ³¨éæï¼ä½¿ç¨åæ°æ® |
| | | // import {expiryAfterSalesAdd, expiryAfterSalesUpdate} from "@/api/customerService/index.js"; // ææ¶æ³¨éæï¼ä½¿ç¨åæ°æ® |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['close']) |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref('') |
| | | const userStore = useUserStore(); |
| | | |
| | | const dialogTitle = computed(() => { |
| | | switch (operationType.value) { |
| | | case 'add': |
| | | return 'æ°å¢ä¸´æå®å'; |
| | | case 'edit': |
| | | return 'ç¼è¾ä¸´æå®å'; |
| | | case 'view': |
| | | return 'æ¥ç临æå®å'; |
| | | default: |
| | | return '临æå®å管ç'; |
| | | } |
| | | }); |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | | id: "", |
| | | productName: "", |
| | | batchNumber: "", |
| | | expiryDate: "", |
| | | stockQuantity: 0, |
| | | customerName: "", |
| | | contactPhone: "", |
| | | problemDesc: "", |
| | | handlerId: "", |
| | | handleDate: "", |
| | | handleResult: "", |
| | | status: 1 |
| | | }, |
| | | rules: { |
| | | productName: [{required: true, message: "请è¾å
¥äº§ååç§°", trigger: "blur"}], |
| | | batchNumber: [{required: true, message: "请è¾å
¥äº§åæ¹å·", trigger: "blur"}], |
| | | expiryDate: [{required: true, message: "è¯·éæ©ä¸´ææ¥æ", trigger: "change"}], |
| | | stockQuantity: [{required: true, message: "请è¾å
¥åºåæ°é", trigger: "blur"}], |
| | | customerName: [{required: true, message: "请è¾å
¥å®¢æ·åç§°", trigger: "blur"}], |
| | | contactPhone: [ |
| | | {required: true, message: "请è¾å
¥èç³»çµè¯", trigger: "blur"}, |
| | | {pattern: /^1[3-9]\d{9}$/, message: "请è¾å
¥æ£ç¡®çææºå·ç ", trigger: "blur"} |
| | | ], |
| | | problemDesc: [{required: true, message: "请è¾å
¥é®é¢æè¿°", trigger: "blur"}], |
| | | } |
| | | }) |
| | | const { form, rules } = toRefs(data); |
| | | const userList = ref([]) |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openDialog = (type, row) => { |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | |
| | | // 模æè·åç¨æ·å表 |
| | | userList.value = [ |
| | | { userId: 1, nickName: "å¼ ä¸" }, |
| | | { userId: 2, nickName: "æå" }, |
| | | { userId: 3, nickName: "çäº" }, |
| | | { userId: 4, nickName: "èµµå
" }, |
| | | { userId: 5, nickName: "åå
«" } |
| | | ]; |
| | | |
| | | if (type === 'add') { |
| | | // æ°å¢æ¶é置表å |
| | | form.value = { |
| | | id: "", |
| | | productName: "", |
| | | batchNumber: "", |
| | | expiryDate: "", |
| | | stockQuantity: 0, |
| | | customerName: "", |
| | | contactPhone: "", |
| | | problemDesc: "", |
| | | handlerId: "", |
| | | handleDate: "", |
| | | handleResult: "", |
| | | status: 1 |
| | | }; |
| | | } else { |
| | | // ç¼è¾ææ¥çæ¶å¡«å
æ°æ® |
| | | form.value = { ...row }; |
| | | if (type === 'edit' && !form.value.handlerId) { |
| | | form.value.handlerId = userStore.id; |
| | | form.value.handleDate = getCurrentDate(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // 模ææäº¤æä½ |
| | | setTimeout(() => { |
| | | console.log("模ææäº¤çæ°æ®:", form.value); |
| | | proxy.$modal.msgSuccess(operationType.value === 'add' ? "æ°å¢æå" : "æ´æ°æå"); |
| | | closeDia(); |
| | | }, 300); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // å
³éå¼¹æ¡ |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | emit('close') |
| | | }; |
| | | |
| | | // è·åå½åæ¥æå¹¶æ ¼å¼å为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, "0"); |
| | | const day = String(today.getDate()).padStart(2, "0"); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | |
| | | defineExpose({ |
| | | openDialog, |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä¸´ææ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.expiryDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">å¤çæ¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.handleDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | <span style = "margin-left: 10px;" class="search_title">å¤çç¶æï¼</span> |
| | | <el-select v-model="searchForm.status" placeholder="è¯·éæ©ç¶æ" @change="handleQuery" style="width: 140px" clearable> |
| | | <el-option label="å¾
å¤ç" :value="1"></el-option> |
| | | <el-option label="å·²å¤ç" :value="2"></el-option> |
| | | </el-select> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button @click="resetQuery" style="margin-left: 10px" |
| | | >éç½®</el-button |
| | | > |
| | | </div> |
| | | </div> |
| | | <div class="table_actions" style="margin-bottom: 10px;"> |
| | | <el-button type="primary" @click="openForm('add')">æ°å¢</el-button> |
| | | <el-button type="danger" @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | > |
| | | <!-- è¡¨æ ¼ææ§½ --> |
| | | <template #status="{ row }"> |
| | | <el-tag :type="row.status === 1 ? 'warning' : 'success'"> |
| | | {{ row.status === 1 ? 'å¾
å¤ç' : 'å·²å¤ç' }} |
| | | </el-tag> |
| | | </template> |
| | | |
| | | <template #operation="{ row }"> |
| | | <el-button type="primary" link @click="openForm('view', row)">æ¥ç</el-button> |
| | | <el-button type="primary" link @click="openForm('edit', row)" v-if="row.status === 1">ç¼è¾</el-button> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import FormDia from "@/views/customerService/expiryAfterSales/components/formDia.vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | // import {expiryAfterSalesDelete, expiryAfterSalesListPage} from "@/api/customerService/index.js"; // ææ¶æ³¨éæï¼ä½¿ç¨åæ°æ® |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | const { proxy } = getCurrentInstance(); |
| | | const userStore = useUserStore() |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | expiryDate: "", |
| | | handleDate: "", |
| | | status: "" |
| | | }, |
| | | tableData: [], |
| | | page: { |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }, |
| | | selectedRows: [], |
| | | tableLoading: false, |
| | | formDia: null, |
| | | tableColumn: [ |
| | | { |
| | | label: "临æäº§ååç§°", |
| | | prop: "productName", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "äº§åæ¹å·", |
| | | prop: "batchNumber", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "ä¸´ææ¥æ", |
| | | prop: "expiryDate", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "åºåæ°é", |
| | | prop: "stockQuantity", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "客æ·åç§°", |
| | | prop: "customerName", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "é®é¢æè¿°", |
| | | prop: "problemDesc", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "å¤çç¶æ", |
| | | prop: "status", |
| | | width: "", |
| | | slot: true, |
| | | }, |
| | | { |
| | | label: "å¤ç人", |
| | | prop: "handlerName", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "å¤çæ¥æ", |
| | | prop: "handleDate", |
| | | width: "", |
| | | }, |
| | | { |
| | | label: "æä½", |
| | | prop: "operation", |
| | | slot: true, |
| | | width: "200", |
| | | }, |
| | | ], |
| | | }); |
| | | |
| | | const { |
| | | searchForm, |
| | | tableData, |
| | | page, |
| | | selectedRows, |
| | | tableLoading, |
| | | formDia, |
| | | tableColumn, |
| | | } = toRefs(data); |
| | | |
| | | // æ¥è¯¢ |
| | | const handleQuery = () => { |
| | | page.value.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | // éæ© |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // éç½® |
| | | const resetQuery = () => { |
| | | proxy.resetForm("queryRef"); |
| | | searchForm.value = { |
| | | expiryDate: "", |
| | | handleDate: "", |
| | | status: "" |
| | | }; |
| | | handleQuery(); |
| | | }; |
| | | |
| | | // å页 |
| | | const pagination = (obj) => { |
| | | page.value.current = obj.page; |
| | | page.value.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | |
| | | // è·ååè¡¨æ°æ® |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | |
| | | // 模æå¼æ¥è¯·æ± |
| | | setTimeout(() => { |
| | | // åæ°æ® |
| | | const mockData = [ |
| | | { |
| | | id: 1, |
| | | productName: "ç»´çç´ Cç", |
| | | batchNumber: "VC20240801", |
| | | expiryDate: "2024-12-15", |
| | | stockQuantity: 150, |
| | | customerName: "å¼ ä¸è¯åº", |
| | | problemDesc: "临è¿ä¿è´¨æéè¦å¤ç", |
| | | status: 1, |
| | | handlerName: "", |
| | | handleDate: "", |
| | | }, |
| | | { |
| | | id: 2, |
| | | productName: "é¿è«è¥¿æè¶å", |
| | | batchNumber: "AM20240715", |
| | | expiryDate: "2024-11-20", |
| | | stockQuantity: 80, |
| | | customerName: "æåå»é¢", |
| | | problemDesc: "åºå积åï¼ä¸´æå¤ç", |
| | | status: 2, |
| | | handlerName: "çäº", |
| | | handleDate: "2024-09-25", |
| | | }, |
| | | { |
| | | id: 3, |
| | | productName: "æåçµé¢ç²", |
| | | batchNumber: "GM20240620", |
| | | expiryDate: "2024-10-30", |
| | | stockQuantity: 200, |
| | | customerName: "èµµå
è¯æ", |
| | | problemDesc: "å£èæ§è¯åï¼éè¦æ¸
çåºå", |
| | | status: 1, |
| | | handlerName: "", |
| | | handleDate: "", |
| | | }, |
| | | { |
| | | id: 4, |
| | | productName: "å¤åç»´çç´ ç", |
| | | batchNumber: "FH20240510", |
| | | expiryDate: "2024-12-01", |
| | | stockQuantity: 300, |
| | | customerName: "é±ä¸è¿é", |
| | | problemDesc: "临æäº§å鿢ç³è¯·", |
| | | status: 2, |
| | | handlerName: "åå
«", |
| | | handleDate: "2024-09-20", |
| | | }, |
| | | { |
| | | id: 5, |
| | | productName: "æ¿èæ ¹é¢ç²", |
| | | batchNumber: "BL20240430", |
| | | expiryDate: "2024-11-10", |
| | | stockQuantity: 120, |
| | | customerName: "å¨ä¹è¯æ¿", |
| | | problemDesc: "æ¹æ¬¡é®é¢ï¼éè¦å¬å", |
| | | status: 1, |
| | | handlerName: "", |
| | | handleDate: "", |
| | | } |
| | | ]; |
| | | |
| | | // ç®åçæç´¢è¿æ»¤ |
| | | let filteredData = mockData; |
| | | |
| | | if (searchForm.value.status !== "" && searchForm.value.status !== null) { |
| | | filteredData = filteredData.filter(item => item.status === searchForm.value.status); |
| | | } |
| | | |
| | | if (searchForm.value.expiryDate) { |
| | | filteredData = filteredData.filter(item => item.expiryDate === searchForm.value.expiryDate); |
| | | } |
| | | |
| | | if (searchForm.value.handleDate) { |
| | | filteredData = filteredData.filter(item => item.handleDate === searchForm.value.handleDate); |
| | | } |
| | | |
| | | // å页å¤ç |
| | | const start = (page.value.current - 1) * page.value.size; |
| | | const end = start + page.value.size; |
| | | const paginatedData = filteredData.slice(start, end); |
| | | |
| | | tableLoading.value = false; |
| | | tableData.value = paginatedData; |
| | | page.value.total = filteredData.length; |
| | | }, 500); // 模æç½ç»å»¶è¿ |
| | | }; |
| | | |
| | | // æå¼å¼¹æ¡ |
| | | const openForm = (type, row) => { |
| | | nextTick(() => { |
| | | formDia.value?.openDialog(type, row) |
| | | }) |
| | | }; |
| | | |
| | | // å é¤ |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map((item) => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | tableLoading.value = true; |
| | | |
| | | // 模æå é¤æä½ |
| | | setTimeout(() => { |
| | | tableLoading.value = false; |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | console.log("模æå é¤çæ°æ®ID:", ids); |
| | | getList(); // éæ°è·åæ°æ® |
| | | }, 300); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="产ååç§°" prop="productName"> |
| | | <el-input |
| | | v-model="queryParams.productName" |
| | | placeholder="请è¾å
¥äº§ååç§°" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¹æ¬¡å·" prop="batchNumber"> |
| | | <el-input |
| | | v-model="queryParams.batchNumber" |
| | | placeholder="请è¾å
¥æ¹æ¬¡å·" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="é忥æ" prop="returnDate"> |
| | | <el-date-picker |
| | | clearable |
| | | v-model="queryParams.returnDate" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | placeholder="è¯·éæ©é忥æ"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="nearExpiryReturnList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="åºå·" type="index" width="50" align="center" /> |
| | | <el-table-column label="产ååç§°" prop="productName" /> |
| | | <el-table-column label="产åè§æ ¼" prop="productSpec" /> |
| | | <el-table-column label="æ¹æ¬¡å·" prop="batchNumber" /> |
| | | <el-table-column label="çäº§æ¥æ" prop="productionDate" align="center"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.productionDate, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å°ææ¥æ" prop="expiryDate" align="center"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.expiryDate, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="éåæ°é" prop="returnQuantity" /> |
| | | <el-table-column label="éååå " prop="returnReason" /> |
| | | <el-table-column label="é忥æ" prop="returnDate" align="center"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.returnDate, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å¤çç¶æ" prop="status" align="center"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="statusOptions" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button size="mini" type="text" icon="Edit" @click="handleUpdate(scope.row)">ä¿®æ¹</el-button> |
| | | <el-button size="mini" type="text" icon="Delete" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹ä¸´æéåå°è´¦å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="800px" append-to-body> |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="产ååç§°" prop="productName"> |
| | | <el-input v-model="form.productName" placeholder="请è¾å
¥äº§ååç§°" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="产åè§æ ¼" prop="productSpec"> |
| | | <el-input v-model="form.productSpec" placeholder="请è¾å
¥äº§åè§æ ¼" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¹æ¬¡å·" prop="batchNumber"> |
| | | <el-input v-model="form.batchNumber" placeholder="请è¾å
¥æ¹æ¬¡å·" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éåæ°é" prop="returnQuantity"> |
| | | <el-input-number v-model="form.returnQuantity" controls-position="right" :min="1" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="çäº§æ¥æ" prop="productionDate"> |
| | | <el-date-picker |
| | | clearable |
| | | v-model="form.productionDate" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | placeholder="è¯·éæ©çäº§æ¥æ"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å°ææ¥æ" prop="expiryDate"> |
| | | <el-date-picker |
| | | clearable |
| | | v-model="form.expiryDate" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | placeholder="è¯·éæ©å°ææ¥æ"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é忥æ" prop="returnDate"> |
| | | <el-date-picker |
| | | clearable |
| | | v-model="form.returnDate" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | placeholder="è¯·éæ©é忥æ"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¤çç¶æ" prop="status"> |
| | | <el-select v-model="form.status" placeholder="è¯·éæ©å¤çç¶æ"> |
| | | <el-option |
| | | v-for="dict in statusOptions" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="éååå " prop="returnReason"> |
| | | <el-input v-model="form.returnReason" type="textarea" placeholder="请è¾å
¥éååå " /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å¤æ³¨" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="NearExpiryReturn"> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { |
| | | nearExpiryReturnListPage, |
| | | nearExpiryReturnAdd, |
| | | nearExpiryReturnUpdate, |
| | | nearExpiryReturnDel, |
| | | nearExpiryReturnDetail |
| | | } from "@/api/qualityManagement/nearExpiryReturn"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const { parseTime } = proxy; |
| | | |
| | | const nearExpiryReturnList = ref([]); |
| | | const open = ref(false); |
| | | const loading = ref(true); |
| | | const showSearch = ref(true); |
| | | const ids = ref([]); |
| | | const single = ref(true); |
| | | const multiple = ref(true); |
| | | const total = ref(0); |
| | | const title = ref(""); |
| | | |
| | | // ç¶æåå
¸ |
| | | const statusOptions = ref([ |
| | | { label: "å¾
å¤ç", value: "0" }, |
| | | { label: "å¤çä¸", value: "1" }, |
| | | { label: "已宿", value: "2" } |
| | | ]); |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | productName: null, |
| | | batchNumber: null, |
| | | returnDate: null |
| | | }, |
| | | rules: { |
| | | productName: [ |
| | | { required: true, message: "产ååç§°ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | productSpec: [ |
| | | { required: true, message: "产åè§æ ¼ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | batchNumber: [ |
| | | { required: true, message: "æ¹æ¬¡å·ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | returnQuantity: [ |
| | | { required: true, message: "éåæ°éä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | productionDate: [ |
| | | { required: true, message: "çäº§æ¥æä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | expiryDate: [ |
| | | { required: true, message: "å°ææ¥æä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | returnDate: [ |
| | | { required: true, message: "é忥æä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | returnReason: [ |
| | | { required: true, message: "éååå ä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | status: [ |
| | | { required: true, message: "å¤çç¶æä¸è½ä¸ºç©º", trigger: "change" } |
| | | ] |
| | | } |
| | | }); |
| | | |
| | | const { queryParams, form, rules } = toRefs(data); |
| | | |
| | | /** æ¥è¯¢ä¸´æéåå°è´¦å表 */ |
| | | function getList() { |
| | | loading.value = true; |
| | | // 使ç¨åæ°æ® |
| | | const mockData = { |
| | | records: [ |
| | | { |
| | | id: 1, |
| | | productName: "ç»´çç´ Cç", |
| | | productSpec: "100mgÃ30ç", |
| | | batchNumber: "VC20240315001", |
| | | productionDate: "2024-03-15", |
| | | expiryDate: "2024-09-15", |
| | | returnQuantity: 50, |
| | | returnReason: "临è¿ä¿è´¨æ", |
| | | returnDate: "2024-09-10", |
| | | status: "1", |
| | | remark: "éåä»åºå¤ç" |
| | | }, |
| | | { |
| | | id: 2, |
| | | productName: "é¿è«è¥¿æè¶å", |
| | | productSpec: "250mgÃ24ç²", |
| | | batchNumber: "AMX20240220002", |
| | | productionDate: "2024-02-20", |
| | | expiryDate: "2024-08-20", |
| | | returnQuantity: 30, |
| | | returnReason: "å
è£
ç ´æä¸ä¸´æ", |
| | | returnDate: "2024-08-18", |
| | | status: "2", |
| | | remark: "已鿝å¤ç" |
| | | }, |
| | | { |
| | | id: 3, |
| | | productName: "æåçµé¢ç²", |
| | | productSpec: "10gÃ12è¢", |
| | | batchNumber: "GML20240110003", |
| | | productionDate: "2024-01-10", |
| | | expiryDate: "2024-07-10", |
| | | returnQuantity: 25, |
| | | returnReason: "临è¿ä¿è´¨æ", |
| | | returnDate: "2024-07-08", |
| | | status: "0", |
| | | remark: "å¾
éæ°å
è£
" |
| | | }, |
| | | { |
| | | id: 4, |
| | | productName: "å¤åç»´çç´ ç", |
| | | productSpec: "60ç/ç¶", |
| | | batchNumber: "VB20240405004", |
| | | productionDate: "2024-04-05", |
| | | expiryDate: "2025-04-05", |
| | | returnQuantity: 80, |
| | | returnReason: "临è¿ä¿è´¨æ", |
| | | returnDate: "2024-09-25", |
| | | status: "1", |
| | | remark: "æ£å¨èç³»é宿¸ é" |
| | | }, |
| | | { |
| | | id: 5, |
| | | productName: "éç", |
| | | productSpec: "600mgÃ100ç", |
| | | batchNumber: "CA20240301005", |
| | | productionDate: "2024-03-01", |
| | | expiryDate: "2024-09-01", |
| | | returnQuantity: 120, |
| | | returnReason: "å
è£
é®é¢ä¸ä¸´æ", |
| | | returnDate: "2024-08-30", |
| | | status: "2", |
| | | remark: "已宿éè´§å¤ç" |
| | | } |
| | | ], |
| | | total: 5 |
| | | }; |
| | | |
| | | // 模æè¿æ»¤é»è¾ |
| | | let filteredRecords = mockData.records; |
| | | |
| | | if (queryParams.value.productName) { |
| | | filteredRecords = filteredRecords.filter(item => |
| | | item.productName.includes(queryParams.value.productName) |
| | | ); |
| | | } |
| | | |
| | | if (queryParams.value.batchNumber) { |
| | | filteredRecords = filteredRecords.filter(item => |
| | | item.batchNumber.includes(queryParams.value.batchNumber) |
| | | ); |
| | | } |
| | | |
| | | if (queryParams.value.returnDate) { |
| | | filteredRecords = filteredRecords.filter(item => |
| | | item.returnDate === queryParams.value.returnDate |
| | | ); |
| | | } |
| | | |
| | | nearExpiryReturnList.value = filteredRecords; |
| | | total.value = filteredRecords.length; |
| | | loading.value = false; |
| | | } |
| | | |
| | | // åæ¶æé® |
| | | function cancel() { |
| | | open.value = false; |
| | | reset(); |
| | | } |
| | | |
| | | // 表åéç½® |
| | | function reset() { |
| | | form.value = { |
| | | id: null, |
| | | productName: null, |
| | | productSpec: null, |
| | | batchNumber: null, |
| | | productionDate: null, |
| | | expiryDate: null, |
| | | returnQuantity: null, |
| | | returnReason: null, |
| | | returnDate: null, |
| | | status: null, |
| | | remark: null |
| | | }; |
| | | proxy.resetForm("formRef"); |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryForm"); |
| | | handleQuery(); |
| | | } |
| | | |
| | | // å¤éæ¡é䏿°æ® |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.id); |
| | | single.value = selection.length !== 1; |
| | | multiple.value = !selection.length; |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd() { |
| | | reset(); |
| | | open.value = true; |
| | | title.value = "æ·»å 临æéåå°è´¦"; |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset(); |
| | | const id = row.id || ids.value; |
| | | |
| | | // 使ç¨åæ°æ®è·å详æ
|
| | | const mockDetail = nearExpiryReturnList.value.find(item => item.id === (Array.isArray(id) ? id[0] : id)); |
| | | if (mockDetail) { |
| | | form.value = { ...mockDetail }; |
| | | open.value = true; |
| | | title.value = "ä¿®æ¹ä¸´æéåå°è´¦"; |
| | | } |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.id != null) { |
| | | // æ¨¡ææ´æ° |
| | | const index = nearExpiryReturnList.value.findIndex(item => item.id === form.value.id); |
| | | if (index !== -1) { |
| | | nearExpiryReturnList.value[index] = { ...form.value }; |
| | | } |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | open.value = false; |
| | | getList(); |
| | | } else { |
| | | // æ¨¡ææ°å¢ |
| | | const newId = Math.max(...nearExpiryReturnList.value.map(item => item.id)) + 1; |
| | | nearExpiryReturnList.value.push({ ...form.value, id: newId }); |
| | | total.value = nearExpiryReturnList.value.length; |
| | | proxy.$modal.msgSuccess("æ°å¢æå"); |
| | | open.value = false; |
| | | getList(); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const deleteIds = row.id || ids.value; |
| | | ElMessageBox.confirm('æ¯å¦ç¡®è®¤å é¤ä¸´æéåå°è´¦ç¼å·ä¸º"' + deleteIds + '"çæ°æ®é¡¹ï¼', "è¦å", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }).then(function() { |
| | | // 模æå é¤ |
| | | if (Array.isArray(deleteIds)) { |
| | | deleteIds.forEach(id => { |
| | | const index = nearExpiryReturnList.value.findIndex(item => item.id === id); |
| | | if (index !== -1) { |
| | | nearExpiryReturnList.value.splice(index, 1); |
| | | } |
| | | }); |
| | | } else { |
| | | const index = nearExpiryReturnList.value.findIndex(item => item.id === deleteIds); |
| | | if (index !== -1) { |
| | | nearExpiryReturnList.value.splice(index, 1); |
| | | } |
| | | } |
| | | getList(); |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | }).catch(() => {}); |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download('quality/nearExpiryReturn/export', { |
| | | ...queryParams.value |
| | | }, `临æéåå°è´¦_${new Date().getTime()}.xlsx`); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | | </script> |