浪潮
1.添加仓库管理页面
2.入库、出库添加新增编辑功能并联调
| | |
| | | }); |
| | | }; |
| | | |
| | | // æ´æ°åºåè®°å½ |
| | | export const updateStockInventory = (params) => { |
| | | return request({ |
| | | url: "/stockInventory/update", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| | | |
| | |
| | | data, |
| | | }); |
| | | } |
| | | |
| | | // æ´æ°åºåºè®°å½ |
| | | export const updateStockOutRecord = (id, data) => { |
| | | return request({ |
| | | url: `/stockOutRecord/${id}`, |
| | | method: "put", |
| | | data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // è·åä»åºå表ï¼åé¡µï¼ |
| | | export const getWarehousePage = (params) => { |
| | | return request({ |
| | | url: "/warehouseInfo/listPage", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // è·åä»åºå表ï¼ä¸åé¡µï¼ |
| | | export const getWarehouseList = (params) => { |
| | | return request({ |
| | | url: "/warehouseInfo/list", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | }; |
| | | |
| | | // æ ¹æ®IDè·åä»åºè¯¦æ
|
| | | export const getWarehouseById = (id) => { |
| | | return request({ |
| | | url: `/warehouseInfo/${id}`, |
| | | method: "get", |
| | | }); |
| | | }; |
| | | |
| | | // æ°å¢ä»åº |
| | | export const addWarehouse = (data) => { |
| | | return request({ |
| | | url: "/warehouseInfo/add", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | }; |
| | | |
| | | // æ´æ°ä»åº |
| | | export const updateWarehouse = (data) => { |
| | | return request({ |
| | | url: "/warehouseInfo/edit", |
| | | method: "post", |
| | | data, |
| | | }); |
| | | }; |
| | | |
| | | // å é¤ä»åº |
| | | export const delWarehouse = (ids) => { |
| | | return request({ |
| | | url: "/warehouseInfo/delete", |
| | | method: "post", |
| | | data: ids, |
| | | }); |
| | | }; |
| | | |
| | | // æ´æ°ä»åºç¶æ |
| | | export const updateWarehouseStatus = (id, status) => { |
| | | return request({ |
| | | url: `/warehouseInfo/${id}/status`, |
| | | method: "put", |
| | | params: { status }, |
| | | }); |
| | | }; |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- è系人åè½å·²è¿ç§»å°è系人管çé¡µé¢ |
| | | <!-- è系人å表 --> |
| | | <el-row :gutter="30" |
| | | v-for="(contact, index) in formYYs.contactList" |
| | | v-for="(contact, index) in form.contactList" |
| | | :key="index"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è系人ï¼" |
| | | prop="contactPerson"> |
| | | <el-form-item :label="index === 0 ? 'è系人ï¼' : ''" |
| | | :prop="'contactList.' + index + '.contactPerson'" |
| | | :rules="{ required: true, message: '请è¾å
¥è系人', trigger: 'blur' }"> |
| | | <el-input v-model="contact.contactPerson" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯ï¼" |
| | | prop="contactPhone"> |
| | | <el-form-item :label="index === 0 ? 'èç³»çµè¯ï¼' : ''" |
| | | :prop="'contactList.' + index + '.contactPhone'" |
| | | :rules="{ required: true, message: '请è¾å
¥èç³»çµè¯', trigger: 'blur' }"> |
| | | <div style="display: flex; align-items: center;width: 100%;"> |
| | | <el-input v-model="contact.contactPhone" |
| | | placeholder="请è¾å
¥" |
| | |
| | | <el-button @click="removeContact(index)" |
| | | type="danger" |
| | | circle |
| | | style="margin-left: 5px;"> |
| | | style="margin-left: 5px;" |
| | | :disabled="form.contactList.length <= 1"> |
| | | <el-icon> |
| | | <Close /> |
| | | </el-icon> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-button @click="addNewContact" |
| | | style="margin-bottom: 10px;">+ æ°å¢è系人</el-button> |
| | | --> |
| | | style="margin-bottom: 10px;" |
| | | type="primary" |
| | | plain>+ æ°å¢è系人</el-button> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´æ¤äººï¼" |
| | |
| | | companyPhone: "", |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | contactList: [ |
| | | { |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | }, |
| | | ], |
| | | maintainer: "", |
| | | maintenanceTime: "", |
| | | basicBankAccount: "", |
| | |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | const addNewContact = () => { |
| | | formYYs.value.contactList.push({ |
| | | form.value.contactList.push({ |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | }); |
| | | }; |
| | | |
| | | const removeContact = index => { |
| | | if (formYYs.value.contactList.length > 1) { |
| | | formYYs.value.contactList.splice(index, 1); |
| | | if (form.value.contactList.length > 1) { |
| | | form.value.contactList.splice(index, 1); |
| | | } |
| | | }; |
| | | // æ¥è¯¢å表 |
| | |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | form.value.maintainer = userStore.nickName; |
| | | formYYs.value.contactList = [ |
| | | form.value.contactList = [ |
| | | { |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | |
| | | if (type === "edit") { |
| | | getCustomer(row.id).then(res => { |
| | | form.value = { ...res.data }; |
| | | formYYs.value.contactList = res.data.contactPerson |
| | | // ä¼å
使ç¨å端è¿åçcontactListæ°ç»ï¼å¦ææ²¡æå使ç¨éå·åéçåç¬¦ä¸²è½¬æ¢ |
| | | if (res.data.contactList && res.data.contactList.length > 0) { |
| | | form.value.contactList = res.data.contactList; |
| | | } else if (res.data.contactPerson) { |
| | | form.value.contactList = res.data.contactPerson |
| | | .split(",") |
| | | .map((item, index) => { |
| | | return { |
| | | contactPerson: item, |
| | | contactPhone: res.data.contactPhone.split(",")[index], |
| | | contactPhone: res.data.contactPhone ? res.data.contactPhone.split(",")[index] : "", |
| | | }; |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | dialogFormVisible.value = true; |
| | |
| | | }; |
| | | // æäº¤æ°å¢ |
| | | const submitAdd = () => { |
| | | if (formYYs.value.contactList.length < 1) { |
| | | if (form.value.contactList.length < 1) { |
| | | return proxy.$modal.msgWarning("请è³å°æ·»å ä¸ä¸ªè系人"); |
| | | } |
| | | form.value.contactPerson = formYYs.value.contactList |
| | | form.value.contactPerson = form.value.contactList |
| | | .map(item => item.contactPerson) |
| | | .join(","); |
| | | form.value.contactPhone = formYYs.value.contactList |
| | | form.value.contactPhone = form.value.contactList |
| | | .map(item => item.contactPhone) |
| | | .join(","); |
| | | addCustomer(form.value).then(res => { |
| | |
| | | }; |
| | | // æäº¤ä¿®æ¹ |
| | | const submitEdit = () => { |
| | | form.value.contactPerson = formYYs.value.contactList |
| | | form.value.contactPerson = form.value.contactList |
| | | .map(item => item.contactPerson) |
| | | .join(","); |
| | | form.value.contactPhone = formYYs.value.contactList |
| | | form.value.contactPhone = form.value.contactList |
| | | .map(item => item.contactPhone) |
| | | .join(","); |
| | | updateCustomer(form.value).then(res => { |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- è系人åè½å·²è¿ç§»å°è系人管çé¡µé¢ |
| | | <!-- è系人å表 --> |
| | | <el-row :gutter="30" |
| | | v-for="(contact, index) in formYYs.contactList" |
| | | v-for="(contact, index) in form.contactList" |
| | | :key="index"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è系人ï¼" |
| | | prop="contactPerson"> |
| | | <el-form-item :label="index === 0 ? 'è系人ï¼' : ''" |
| | | :prop="'contactList.' + index + '.contactPerson'" |
| | | :rules="{ required: true, message: '请è¾å
¥è系人', trigger: 'blur' }"> |
| | | <el-input v-model="contact.contactPerson" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯ï¼" |
| | | prop="contactPhone"> |
| | | <el-form-item :label="index === 0 ? 'èç³»çµè¯ï¼' : ''" |
| | | :prop="'contactList.' + index + '.contactPhone'" |
| | | :rules="{ required: true, message: '请è¾å
¥èç³»çµè¯', trigger: 'blur' }"> |
| | | <div style="display: flex; align-items: center;width: 100%;"> |
| | | <el-input v-model="contact.contactPhone" |
| | | placeholder="请è¾å
¥" |
| | |
| | | <el-button @click="removeContact(index)" |
| | | type="danger" |
| | | circle |
| | | style="margin-left: 5px;"> |
| | | style="margin-left: 5px;" |
| | | :disabled="form.contactList.length <= 1"> |
| | | <el-icon> |
| | | <Close /> |
| | | </el-icon> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-button @click="addNewContact" |
| | | style="margin-bottom: 10px;">+ æ°å¢è系人</el-button> |
| | | --> |
| | | style="margin-bottom: 10px;" |
| | | type="primary" |
| | | plain>+ æ°å¢è系人</el-button> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´æ¤äººï¼" |
| | |
| | | companyPhone: "", |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | contactList: [ |
| | | { |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | }, |
| | | ], |
| | | maintainer: "", |
| | | maintenanceTime: "", |
| | | basicBankAccount: "", |
| | |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | const addNewContact = () => { |
| | | formYYs.value.contactList.push({ |
| | | form.value.contactList.push({ |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | }); |
| | | }; |
| | | |
| | | const removeContact = index => { |
| | | if (formYYs.value.contactList.length > 1) { |
| | | formYYs.value.contactList.splice(index, 1); |
| | | if (form.value.contactList.length > 1) { |
| | | form.value.contactList.splice(index, 1); |
| | | } |
| | | }; |
| | | // æ¥è¯¢å表 |
| | |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | form.value.maintainer = userStore.nickName; |
| | | formYYs.value.contactList = [ |
| | | form.value.contactList = [ |
| | | { |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | |
| | | if (type === "edit") { |
| | | getCustomer(row.id).then(res => { |
| | | form.value = { ...res.data }; |
| | | formYYs.value.contactList = res.data.contactPerson |
| | | // ä¼å
使ç¨å端è¿åçcontactListæ°ç»ï¼å¦ææ²¡æå使ç¨éå·åéçåç¬¦ä¸²è½¬æ¢ |
| | | if (res.data.contactList && res.data.contactList.length > 0) { |
| | | form.value.contactList = res.data.contactList; |
| | | } else if (res.data.contactPerson) { |
| | | form.value.contactList = res.data.contactPerson |
| | | .split(",") |
| | | .map((item, index) => { |
| | | return { |
| | | contactPerson: item, |
| | | contactPhone: res.data.contactPhone.split(",")[index], |
| | | contactPhone: res.data.contactPhone ? res.data.contactPhone.split(",")[index] : "", |
| | | }; |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | dialogFormVisible.value = true; |
| | |
| | | }; |
| | | // æäº¤æ°å¢ |
| | | const submitAdd = () => { |
| | | if (formYYs.value.contactList.length < 1) { |
| | | if (form.value.contactList.length < 1) { |
| | | return proxy.$modal.msgWarning("请è³å°æ·»å ä¸ä¸ªè系人"); |
| | | } |
| | | form.value.contactPerson = formYYs.value.contactList |
| | | form.value.contactPerson = form.value.contactList |
| | | .map(item => item.contactPerson) |
| | | .join(","); |
| | | form.value.contactPhone = formYYs.value.contactList |
| | | form.value.contactPhone = form.value.contactList |
| | | .map(item => item.contactPhone) |
| | | .join(","); |
| | | addCustomer(form.value).then(res => { |
| | |
| | | }; |
| | | // æäº¤ä¿®æ¹ |
| | | const submitEdit = () => { |
| | | form.value.contactPerson = formYYs.value.contactList |
| | | form.value.contactPerson = form.value.contactList |
| | | .map(item => item.contactPerson) |
| | | .join(","); |
| | | form.value.contactPhone = formYYs.value.contactList |
| | | form.value.contactPhone = form.value.contactList |
| | | .map(item => item.contactPhone) |
| | | .join(","); |
| | | updateCustomer(form.value).then(res => { |
| | |
| | | > |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="handleAdd">æ°å¢</el-button> |
| | | <el-button type="primary" @click="handleBatchApprove">审æ¹</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="120" align="center" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | v-if="scope.row.approvalStatus !== 1 && scope.row.approvalStatus !== '1' && scope.row.approvalStatus !== 'approved' && scope.row.approvalStatus !== 'APPROVED'" |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="handleEdit(scope.row)">ç¼è¾</el-button> |
| | | <span v-else style="color: #999; font-size: 12px;">å·²éè¿</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | |
| | | @pagination="paginationChange" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- æ°å¢/ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="dialogVisible" |
| | | :title="dialogTitle" |
| | | width="800" |
| | | @close="closeDialog"> |
| | | <el-form ref="formRef" |
| | | :model="formState" |
| | | label-width="140px" |
| | | label-position="top"> |
| | | <el-form-item label="产ååç§°" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©äº§å', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-button type="primary" |
| | | @click="showProductSelect = true"> |
| | | {{ formState.productName ? formState.productName : 'éæ©äº§å' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | <el-form-item label="è§æ ¼" |
| | | prop="productModelName"> |
| | | <el-input v-model="formState.productModelName" disabled /> |
| | | </el-form-item> |
| | | <el-form-item label="åä½" |
| | | prop="unit"> |
| | | <el-input v-model="formState.unit" disabled /> |
| | | </el-form-item> |
| | | <el-form-item label="åºåç±»å" |
| | | prop="type" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©åºåç±»å', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.type" |
| | | placeholder="è¯·éæ©åºåç±»å" |
| | | :disabled="isEdit"> |
| | | <el-option label="åæ ¼åºå" |
| | | value="qualified" /> |
| | | <el-option label="ä¸åæ ¼åºå" |
| | | value="unqualified" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åºåºæ°é" |
| | | prop="qualitity" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请è¾å
¥åºåºæ°é', |
| | | trigger: 'blur', |
| | | }, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (formState.maxStock > 0 && value > formState.maxStock) { |
| | | callback('åºåºæ°éä¸è½è¶
è¿å½åæ¹å·åºå ' + formState.maxStock); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }, |
| | | trigger: 'blur', |
| | | } |
| | | ]"> |
| | | <el-input-number v-model="formState.qualitity" |
| | | :step="1" |
| | | :min="1" |
| | | :max="formState.maxStock > 0 ? formState.maxStock : undefined" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¹å·" |
| | | prop="batchNo" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©æ¹å·', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.batchNo" |
| | | placeholder="è¯·éæ©æ¹å·" |
| | | clearable |
| | | :disabled="isEdit" |
| | | @change="handleBatchNoChange" |
| | | style="width: 100%"> |
| | | <el-option v-for="batch in batchNoList" |
| | | :key="batch" |
| | | :label="batch + ' (åºå: ' + (batchNoStockMap[batch] || 0) + ')'" |
| | | :value="batch" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="formState.batchNo && batchNoStockMap[formState.batchNo]" |
| | | label="å½åæ¹å·åºå" |
| | | prop="currentStock"> |
| | | <el-input v-model="batchNoStockMap[formState.batchNo]" disabled /> |
| | | </el-form-item> |
| | | <el-form-item v-if="isEdit" |
| | | label="æ¥æº" |
| | | prop="recordType"> |
| | | <el-select v-model="formState.recordType" |
| | | placeholder="è¯·éæ©æ¥æº" |
| | | disabled> |
| | | <el-option v-for="item in stockRecordTypeOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" |
| | | prop="remark"> |
| | | <el-input v-model="formState.remark" |
| | | type="textarea" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- 产åéæ©å¼¹çª --> |
| | | <ProductSelectDialog v-model="showProductSelect" |
| | | @confirm="handleProductSelect" |
| | | :top-product-parent-id="props.topParentProductId" |
| | | request-url="/basic/product/pageModelAndQua" |
| | | single /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeDialog">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import { ref } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import { ref, reactive, toRefs, computed, getCurrentInstance, watch, onMounted } from "vue"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | import { |
| | | getStockOutPage, |
| | | delPendingStockOut, |
| | | batchApproveStockOutRecords, |
| | | updateStockOutRecord, |
| | | } from "@/api/inventoryManagement/stockOut.js"; |
| | | import { |
| | | findAllQualifiedStockOutRecordTypeOptions, |
| | | findAllUnQualifiedStockOutRecordTypeOptions, |
| | | } from "@/api/basicData/enum.js"; |
| | | import { addStockOutRecordOnly } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import { addUnqualifiedStockOutRecordOnly } from "@/api/inventoryManagement/stockUninventory.js"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const { proxy } = getCurrentInstance(); |
| | |
| | | const tableLoading = ref(false); |
| | | // æ¥æºç±»åé项 |
| | | const stockRecordTypeOptions = ref([]); |
| | | // æ¹å·å表ï¼ä»batchNoMapsè·åï¼ |
| | | const batchNoList = ref([]); |
| | | // æ¹å·åºåæ å° |
| | | const batchNoStockMap = ref({}); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | |
| | | // å¯¹è¯æ¡ç¸å
³ |
| | | const dialogVisible = ref(false); |
| | | const dialogType = ref('add'); // 'add' æ 'edit' |
| | | const dialogTitle = computed(() => dialogType.value === 'add' ? 'æ°å¢åºåºè®°å½' : 'ç¼è¾åºåºè®°å½'); |
| | | const isEdit = computed(() => dialogType.value === 'edit'); |
| | | const formRef = ref(); |
| | | const showProductSelect = ref(false); |
| | | |
| | | // è¡¨åæ°æ® |
| | | const formState = ref({ |
| | | id: undefined, |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | type: undefined, |
| | | qualitity: 0, |
| | | batchNo: null, |
| | | recordType: "", |
| | | remark: "", |
| | | maxStock: 0, // å½åé䏿¹å·çæå¤§åºå |
| | | }); |
| | | |
| | | // æ¹å·ä¸ºç©ºæ¶è½¬ä¸º null |
| | | watch( |
| | | () => formState.value.batchNo, |
| | | val => { |
| | | if (val === "") { |
| | | formState.value.batchNo = null; |
| | | } |
| | | } |
| | | ); |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | return "warning"; |
| | | }; |
| | | |
| | | // æ°å¢ |
| | | const handleAdd = () => { |
| | | dialogType.value = 'add'; |
| | | resetForm(); |
| | | // æ ¹æ®å½åtab设置é»è®¤åºåç±»å |
| | | formState.value.type = props.type === '0' ? 'qualified' : 'unqualified'; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // ç¼è¾ |
| | | const handleEdit = (row) => { |
| | | dialogType.value = 'edit'; |
| | | resetForm(); |
| | | // å¡«å
è¡¨åæ°æ® |
| | | formState.value = { |
| | | id: row.id, |
| | | productId: row.productId, |
| | | productModelId: row.productModelId, |
| | | productName: row.productName, |
| | | productModelName: row.model, |
| | | unit: row.unit, |
| | | type: props.type === '0' ? 'qualified' : 'unqualified', |
| | | qualitity: row.stockOutNum, |
| | | batchNo: row.batchNo, |
| | | recordType: row.recordType, |
| | | remark: row.remark || "", |
| | | maxStock: row.stockOutNum || 0, // ç¼è¾æ¶ä½¿ç¨å½ååºåºæ°éä½ä¸ºæå¤§åºåï¼å 为æ¯ä¿®æ¹å·²æè®°å½ï¼ |
| | | }; |
| | | // ç¼è¾æ¶ä»batchNoMapsè·åæ¹å·å表 |
| | | if (row.batchNoMaps && Object.keys(row.batchNoMaps).length > 0) { |
| | | batchNoList.value = Object.keys(row.batchNoMaps); |
| | | batchNoStockMap.value = row.batchNoMaps; |
| | | } else if (row.batchNo) { |
| | | batchNoList.value = [row.batchNo]; |
| | | batchNoStockMap.value = { [row.batchNo]: row.stockOutNum || 0 }; |
| | | } else { |
| | | batchNoList.value = []; |
| | | batchNoStockMap.value = {}; |
| | | } |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // é置表å |
| | | const resetForm = () => { |
| | | formState.value = { |
| | | id: undefined, |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | type: undefined, |
| | | qualitity: 0, |
| | | batchNo: null, |
| | | recordType: "", |
| | | remark: "", |
| | | maxStock: 0, |
| | | }; |
| | | batchNoList.value = []; |
| | | batchNoStockMap.value = {}; |
| | | }; |
| | | |
| | | // å
³éå¯¹è¯æ¡ |
| | | const closeDialog = () => { |
| | | dialogVisible.value = false; |
| | | resetForm(); |
| | | }; |
| | | |
| | | // 产åéæ©å¤ç |
| | | const handleProductSelect = async products => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | formState.value.productId = product.productId; |
| | | formState.value.productName = product.productName; |
| | | formState.value.productModelName = product.model; |
| | | formState.value.productModelId = product.id; |
| | | formState.value.unit = product.unit; |
| | | // ä»batchNoMapsè·åæ¹å·å表ååºå |
| | | if (product.batchNoMaps && Object.keys(product.batchNoMaps).length > 0) { |
| | | batchNoList.value = Object.keys(product.batchNoMaps); |
| | | batchNoStockMap.value = product.batchNoMaps; |
| | | } else { |
| | | batchNoList.value = []; |
| | | batchNoStockMap.value = {}; |
| | | } |
| | | // æ¸
ç©ºå·²éæ©çæ¹å·åæå¤§åºå |
| | | formState.value.batchNo = null; |
| | | formState.value.maxStock = 0; |
| | | showProductSelect.value = false; |
| | | // 触å表åéªè¯æ´æ° |
| | | proxy.$refs["formRef"]?.validateField("productModelId"); |
| | | } |
| | | }; |
| | | |
| | | // æ¹å·éæ©ååå¤ç |
| | | const handleBatchNoChange = (batchNo) => { |
| | | if (batchNo && batchNoStockMap.value[batchNo]) { |
| | | formState.value.maxStock = batchNoStockMap.value[batchNo]; |
| | | // 妿å½ååºåºæ°éè¶
è¿æå¤§åºåï¼èªå¨è°æ´ä¸ºæå¤§åºå |
| | | if (formState.value.qualitity > formState.value.maxStock) { |
| | | formState.value.qualitity = formState.value.maxStock; |
| | | } |
| | | } else { |
| | | formState.value.maxStock = 0; |
| | | } |
| | | }; |
| | | |
| | | // æäº¤è¡¨å |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // éªè¯æ¯å¦éæ©äºäº§å |
| | | if (!formState.value.productModelId) { |
| | | ElMessage.error("è¯·éæ©äº§å"); |
| | | return; |
| | | } |
| | | |
| | | if (dialogType.value === 'add') { |
| | | submitAdd(); |
| | | } else { |
| | | submitEdit(); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // æäº¤æ°å¢ |
| | | const submitAdd = () => { |
| | | const params = { ...formState.value }; |
| | | |
| | | if (formState.value.type === "qualified") { |
| | | addStockOutRecordOnly(params).then(res => { |
| | | ElMessage.success("æ°å¢æå"); |
| | | closeDialog(); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("æ°å¢å¤±è´¥"); |
| | | }); |
| | | } else { |
| | | addUnqualifiedStockOutRecordOnly(params).then(res => { |
| | | ElMessage.success("æ°å¢æå"); |
| | | closeDialog(); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("æ°å¢å¤±è´¥"); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // æäº¤ç¼è¾ |
| | | const submitEdit = () => { |
| | | const params = { |
| | | productId: formState.value.productId, |
| | | productModelId: formState.value.productModelId, |
| | | productName: formState.value.productName, |
| | | model: formState.value.productModelName, |
| | | unit: formState.value.unit, |
| | | batchNo: formState.value.batchNo, |
| | | stockOutNum: formState.value.qualitity, |
| | | recordType: formState.value.recordType, |
| | | remark: formState.value.remark, |
| | | }; |
| | | |
| | | updateStockOutRecord(formState.value.id, params).then(() => { |
| | | ElMessage.success("ç¼è¾æå"); |
| | | closeDialog(); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("ç¼è¾å¤±è´¥"); |
| | | }); |
| | | }; |
| | | |
| | | // è·åæ¥æºç±»åé项 |
| | | const fetchStockRecordTypeOptions = () => { |
| | | if (props.type === "0") { |
| | |
| | | </el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="handleAdd">æ°å¢</el-button> |
| | | <el-button type="primary" @click="handleBatchApprove">审æ¹</el-button> |
| | | <el-button @click="handleOut">导åº</el-button> |
| | | <el-button type="danger" |
| | |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="120" align="center" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | v-if="scope.row.approvalStatus !== 1 && scope.row.approvalStatus !== '1' && scope.row.approvalStatus !== 'approved' && scope.row.approvalStatus !== 'APPROVED'" |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | @click="handleEdit(scope.row)">ç¼è¾</el-button> |
| | | <span v-else style="color: #999; font-size: 12px;">å·²éè¿</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" |
| | | :total="total" |
| | |
| | | :limit="page.size" |
| | | @pagination="pageProductChange"/> |
| | | </div> |
| | | |
| | | <!-- æ°å¢/ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="dialogVisible" |
| | | :title="dialogTitle" |
| | | width="800" |
| | | @close="closeDialog"> |
| | | <el-form ref="formRef" |
| | | :model="formState" |
| | | label-width="140px" |
| | | label-position="top"> |
| | | <el-form-item label="产ååç§°" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©äº§å', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-button type="primary" |
| | | @click="showProductSelect = true"> |
| | | {{ formState.productName ? formState.productName : 'éæ©äº§å' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | <el-form-item label="è§æ ¼" |
| | | prop="productModelName"> |
| | | <el-input v-model="formState.productModelName" disabled /> |
| | | </el-form-item> |
| | | <el-form-item label="åä½" |
| | | prop="unit"> |
| | | <el-input v-model="formState.unit" disabled /> |
| | | </el-form-item> |
| | | <el-form-item label="åºåç±»å" |
| | | prop="type" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©åºåç±»å', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.type" |
| | | placeholder="è¯·éæ©åºåç±»å" |
| | | :disabled="isEdit"> |
| | | <el-option label="åæ ¼åºå" |
| | | value="qualified" /> |
| | | <el-option label="ä¸åæ ¼åºå" |
| | | value="unqualified" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åºåæ°é" |
| | | prop="qualitity"> |
| | | <el-input-number v-model="formState.qualitity" |
| | | :step="1" |
| | | :min="1" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¹å·" |
| | | prop="batchNo"> |
| | | <el-input v-model="formState.batchNo" |
| | | placeholder="请è¾å
¥æ¹å·" |
| | | :disabled="isEdit" /> |
| | | </el-form-item> |
| | | <el-form-item label="åºä½" |
| | | prop="warehouseId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©åºä½', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.warehouseId" |
| | | placeholder="è¯·éæ©åºä½" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option v-for="warehouse in warehouseList" |
| | | :key="warehouse.id" |
| | | :label="warehouse.warehouseName + ' - ' + warehouse.location" |
| | | :value="warehouse.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="isEdit" |
| | | label="æ¥æº" |
| | | prop="recordType"> |
| | | <el-select v-model="formState.recordType" |
| | | placeholder="è¯·éæ©æ¥æº" |
| | | disabled> |
| | | <el-option v-for="item in stockRecordTypeOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="formState.type === 'qualified'" |
| | | label="åºåé¢è¦æ°é" |
| | | prop="warnNum"> |
| | | <el-input-number v-model="formState.warnNum" |
| | | :step="1" |
| | | :min="0" |
| | | :max="formState.qualitity" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" |
| | | prop="remark"> |
| | | <el-input v-model="formState.remark" |
| | | type="textarea" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- 产åéæ©å¼¹çª --> |
| | | <ProductSelectDialog v-model="showProductSelect" |
| | | @confirm="handleProductSelect" |
| | | :top-product-parent-id="topParentProductId" |
| | | single /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeDialog">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import { |
| | | ref, |
| | | reactive, |
| | | toRefs, |
| | | onMounted, |
| | | getCurrentInstance, |
| | | computed, |
| | | watch, |
| | | } from "vue"; |
| | | import {ElMessageBox} from "element-plus"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import { |
| | | getStockInRecordListPage, |
| | | batchDeletePendingStockInRecords, |
| | | batchApproveStockInRecords, |
| | | updateStockInRecord, |
| | | } from "@/api/inventoryManagement/stockInRecord.js"; |
| | | import { addStockInRecordOnly } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import { createStockUnInventory } from "@/api/inventoryManagement/stockUninventory.js"; |
| | | import { |
| | | findAllQualifiedStockInRecordTypeOptions, findAllUnQualifiedStockInRecordTypeOptions, |
| | | } from "@/api/basicData/enum.js"; |
| | | import { getWarehouseList } from "@/api/inventoryManagement/warehouse.js"; |
| | | |
| | | const {proxy} = getCurrentInstance(); |
| | | |
| | |
| | | const tableLoading = ref(false); |
| | | // æ¥æºç±»åé项 |
| | | const stockRecordTypeOptions = ref([]); |
| | | // ä»åºå表 |
| | | const warehouseList = ref([]); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | |
| | | }, |
| | | }); |
| | | const {searchForm} = toRefs(data); |
| | | |
| | | // å¯¹è¯æ¡ç¸å
³ |
| | | const dialogVisible = ref(false); |
| | | const dialogType = ref('add'); // 'add' æ 'edit' |
| | | const dialogTitle = computed(() => dialogType.value === 'add' ? 'æ°å¢å
¥åºè®°å½' : 'ç¼è¾å
¥åºè®°å½'); |
| | | const isEdit = computed(() => dialogType.value === 'edit'); |
| | | const formRef = ref(); |
| | | const showProductSelect = ref(false); |
| | | |
| | | // è¡¨åæ°æ®ï¼ä»¿ç
§New.vue使ç¨formStateï¼ |
| | | const formState = ref({ |
| | | id: undefined, |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | type: undefined, |
| | | qualitity: 0, |
| | | batchNo: null, |
| | | warehouseId: undefined, |
| | | warnNum: 0, |
| | | recordType: "", |
| | | remark: "", |
| | | }); |
| | | |
| | | // æ¹å·ä¸ºç©ºæ¶è½¬ä¸º null |
| | | watch( |
| | | () => formState.value.batchNo, |
| | | val => { |
| | | if (val === "") { |
| | | formState.value.batchNo = null; |
| | | } |
| | | } |
| | | ); |
| | | |
| | | // æ¥è¯¢å表 |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | |
| | | const expandedRowKeys = ref([]); |
| | | |
| | | // æ°å¢ |
| | | const handleAdd = () => { |
| | | dialogType.value = 'add'; |
| | | resetForm(); |
| | | // æ ¹æ®å½åtab设置é»è®¤åºåç±»å |
| | | formState.value.type = props.type === '0' ? 'qualified' : 'unqualified'; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // ç¼è¾ |
| | | const handleEdit = (row) => { |
| | | dialogType.value = 'edit'; |
| | | resetForm(); |
| | | // å¡«å
è¡¨åæ°æ® |
| | | formState.value = { |
| | | id: row.id, |
| | | productId: row.productId, |
| | | productModelId: row.productModelId, |
| | | productName: row.productName, |
| | | productModelName: row.model, |
| | | unit: row.unit, |
| | | type: props.type === '0' ? 'qualified' : 'unqualified', |
| | | qualitity: row.stockInNum, |
| | | batchNo: row.batchNo, |
| | | warehouseId: row.warehouseId, |
| | | warnNum: row.warnNum || 0, |
| | | recordType: row.recordType, |
| | | remark: row.remark || "", |
| | | }; |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // é置表å |
| | | const resetForm = () => { |
| | | formState.value = { |
| | | id: undefined, |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | type: undefined, |
| | | qualitity: 0, |
| | | batchNo: null, |
| | | warehouseId: undefined, |
| | | warnNum: 0, |
| | | recordType: "", |
| | | remark: "", |
| | | }; |
| | | }; |
| | | |
| | | // å
³éå¯¹è¯æ¡ |
| | | const closeDialog = () => { |
| | | dialogVisible.value = false; |
| | | resetForm(); |
| | | }; |
| | | |
| | | // 产åéæ©å¤çï¼ä»¿ç
§New.vueï¼ |
| | | const handleProductSelect = async products => { |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | | formState.value.productId = product.productId; |
| | | formState.value.productName = product.productName; |
| | | formState.value.productModelName = product.model; |
| | | formState.value.productModelId = product.id; |
| | | formState.value.unit = product.unit; |
| | | showProductSelect.value = false; |
| | | // 触å表åéªè¯æ´æ° |
| | | proxy.$refs["formRef"]?.validateField("productModelId"); |
| | | } |
| | | }; |
| | | |
| | | // æäº¤è¡¨åï¼ä»¿ç
§New.vueï¼ |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // éªè¯æ¯å¦éæ©äºäº§ååè§æ ¼ |
| | | if (!formState.value.productModelId) { |
| | | ElMessage.error("è¯·éæ©äº§å"); |
| | | return; |
| | | } |
| | | |
| | | if (dialogType.value === 'add') { |
| | | submitAdd(); |
| | | } else { |
| | | submitEdit(); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // æäº¤æ°å¢ |
| | | const submitAdd = () => { |
| | | const params = { ...formState.value }; |
| | | |
| | | if (formState.value.type === "qualified") { |
| | | addStockInRecordOnly(params).then(res => { |
| | | ElMessage.success("æ°å¢æå"); |
| | | closeDialog(); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("æ°å¢å¤±è´¥"); |
| | | }); |
| | | } else { |
| | | params.warnNum = 0; |
| | | createStockUnInventory(params).then(res => { |
| | | ElMessage.success("æ°å¢æå"); |
| | | closeDialog(); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("æ°å¢å¤±è´¥"); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // è·åä»åºå表 |
| | | const fetchWarehouseList = () => { |
| | | getWarehouseList({ status: true }).then(res => { |
| | | warehouseList.value = res.data || []; |
| | | }).catch(() => { |
| | | ElMessage.error("è·åä»åºå表失败"); |
| | | }); |
| | | }; |
| | | |
| | | // æäº¤ç¼è¾ |
| | | const submitEdit = () => { |
| | | const params = { |
| | | productId: formState.value.productId, |
| | | productModelId: formState.value.productModelId, |
| | | productName: formState.value.productName, |
| | | model: formState.value.productModelName, |
| | | unit: formState.value.unit, |
| | | batchNo: formState.value.batchNo, |
| | | warehouseId: formState.value.warehouseId, |
| | | stockInNum: formState.value.qualitity, |
| | | recordType: formState.value.recordType, |
| | | remark: formState.value.remark, |
| | | warnNum: formState.value.warnNum, |
| | | }; |
| | | |
| | | updateStockInRecord(formState.value.id, params).then(() => { |
| | | ElMessage.success("ç¼è¾æå"); |
| | | closeDialog(); |
| | | getList(); |
| | | }).catch(() => { |
| | | ElMessage.error("ç¼è¾å¤±è´¥"); |
| | | }); |
| | | }; |
| | | |
| | | const handleBatchApprove = () => { |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | |
| | | onMounted(() => { |
| | | getList(); |
| | | fetchStockRecordTypeOptions(); |
| | | fetchWarehouseList(); |
| | | }); |
| | | |
| | | watch( |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"></style> |
| | | |
| | | |
| | | |
| | |
| | | <el-table-column label="åºåé¢è¦æ°é" prop="warnNum" show-overflow-tooltip /> |
| | | <el-table-column label="夿³¨" prop="remark" show-overflow-tooltip /> |
| | | <el-table-column label="æè¿æ´æ°æ¶é´" prop="updateTime" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="æä½" min-width="90" align="center"> |
| | | <el-table-column fixed="right" label="æä½" min-width="120" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="showEditModal(scope.row)">ç¼è¾</el-button> |
| | | <el-button link type="primary" @click="showSubtractModal(scope.row)" :disabled="((scope.row.qualifiedUnLockedQuantity || 0) + (scope.row.qualifiedPendingOutQuantity || 0) <= 0) && ((scope.row.unQualifiedUnLockedQuantity || 0) + (scope.row.unQualifiedPendingOutQuantity || 0) <= 0)">é¢ç¨</el-button> |
| | | <el-button link type="primary" v-if="scope.row.unQualifiedUnLockedQuantity > 0 || scope.row.qualifiedUnLockedQuantity > 0" @click="showFrozenModal(scope.row)">å»ç»</el-button> |
| | | <el-button link type="primary" v-if="scope.row.qualifiedLockedQuantity > 0 || scope.row.unQualifiedLockedQuantity > 0" @click="showThawModal(scope.row)">è§£å»</el-button> |
| | |
| | | <new-stock-inventory v-if="isShowNewModal" |
| | | v-model:visible="isShowNewModal" |
| | | :top-product-parent-id="props.productId" |
| | | @completed="handleQuery" /> |
| | | |
| | | <edit-stock-inventory |
| | | v-model:visible="isShowEditModal" |
| | | :record="record" |
| | | @completed="handleQuery" /> |
| | | |
| | | <subtract-stock-inventory v-if="isShowSubtractModal" |
| | |
| | | }); |
| | | |
| | | const NewStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/New.vue")); |
| | | const EditStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/Edit.vue")); |
| | | const SubtractStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/Subtract.vue")); |
| | | const ImportStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/Import.vue")); |
| | | const FrozenAndThawStockInventory = defineAsyncComponent(() => import("@/views/inventoryManagement/stockManagement/FrozenAndThaw.vue")); |
| | |
| | | const total = ref(0) |
| | | // æ¯å¦æ¾ç¤ºæ°å¢å¼¹æ¡ |
| | | const isShowNewModal = ref(false) |
| | | // æ¯å¦æ¾ç¤ºç¼è¾å¼¹æ¡ |
| | | const isShowEditModal = ref(false) |
| | | // æ¯å¦æ¾ç¤ºé¢ç¨å¼¹æ¡ |
| | | const isShowSubtractModal = ref(false) |
| | | // æ¯å¦æ¾ç¤ºå»ç»/è§£å»å¼¹æ¡ |
| | |
| | | } |
| | | }; |
| | | |
| | | // ç¹å»ç¼è¾ |
| | | const showEditModal = (row) => { |
| | | record.value = row |
| | | isShowEditModal.value = true |
| | | } |
| | | |
| | | // ç¹å»é¢ç¨ |
| | | const showSubtractModal = (row) => { |
| | | record.value = row |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form" style="margin-bottom: 10px"> |
| | | <div> |
| | | <span class="search_title">ä»åºåç§°ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.warehouseName" |
| | | placeholder="请è¾å
¥ä»åºåç§°" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">ä»åºä½ç½®ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.location" |
| | | placeholder="请è¾å
¥ä»åºä½ç½®" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | <span class="search_title ml10">è´è´£äººï¼</span> |
| | | <el-input |
| | | v-model="searchForm.managerName" |
| | | placeholder="请è¾å
¥è´è´£äºº" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px" |
| | | >æç´¢</el-button |
| | | > |
| | | <el-button @click="handleReset">éç½®</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" @click="handleAdd">æ°å¢</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | @selection-change="handleSelectionChange" |
| | | style="width: 100%" |
| | | height="calc(100vh - 18.5em)" |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | <el-table-column |
| | | label="ä»åºåç§°" |
| | | prop="warehouseName" |
| | | min-width="150" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="ä»åºä½ç½®" |
| | | prop="location" |
| | | min-width="200" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="è´è´£äºº" |
| | | prop="managerName" |
| | | min-width="120" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="èç³»çµè¯" |
| | | prop="contactPhone" |
| | | min-width="150" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column label="ç¶æ" prop="status" width="100" align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status ? 'success' : 'info'" size="small"> |
| | | {{ scope.row.status ? 'å¯ç¨' : 'åç¨' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="å建æ¶é´" |
| | | prop="createTime" |
| | | min-width="180" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column label="æä½" width="150" align="center" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="handleEdit(scope.row)">ç¼è¾</el-button> |
| | | <el-button link type="danger" size="small" @click="handleRowDelete(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" |
| | | :limit="page.size" |
| | | @pagination="paginationChange" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- æ°å¢/ç¼è¾å¯¹è¯æ¡ --> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="dialogTitle" |
| | | width="600" |
| | | @close="closeDialog" |
| | | > |
| | | <el-form |
| | | ref="formRef" |
| | | :model="formState" |
| | | label-width="100px" |
| | | :rules="formRules" |
| | | > |
| | | <el-form-item label="ä»åºåç§°" prop="warehouseName"> |
| | | <el-input |
| | | v-model="formState.warehouseName" |
| | | placeholder="请è¾å
¥ä»åºåç§°" |
| | | maxlength="50" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä»åºä½ç½®" prop="location"> |
| | | <el-input |
| | | v-model="formState.location" |
| | | placeholder="请è¾å
¥ä»åºä½ç½®" |
| | | maxlength="200" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="è´è´£äºº" prop="managerId"> |
| | | <el-select |
| | | v-model="formState.managerId" |
| | | placeholder="è¯·éæ©è´è´£äºº" |
| | | clearable |
| | | filterable |
| | | style="width: 100%" |
| | | @change="handleManagerChange" |
| | | > |
| | | <el-option |
| | | v-for="user in userList" |
| | | :key="user.userId" |
| | | :label="user.nickName" |
| | | :value="user.userId" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="èç³»çµè¯" prop="contactPhone"> |
| | | <el-input |
| | | v-model="formState.contactPhone" |
| | | placeholder="请è¾å
¥èç³»çµè¯" |
| | | maxlength="20" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="formState.status"> |
| | | <el-radio :value="true">å¯ç¨</el-radio> |
| | | <el-radio :value="false">åç¨</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeDialog">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import { ref, reactive, computed, getCurrentInstance, onMounted } from "vue"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import { |
| | | getWarehousePage, |
| | | addWarehouse, |
| | | updateWarehouse, |
| | | delWarehouse, |
| | | updateWarehouseStatus, |
| | | } from "@/api/inventoryManagement/warehouse.js"; |
| | | import { listUser } from "@/api/system/user.js"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | }); |
| | | const total = ref(0); |
| | | |
| | | // æç´¢è¡¨å |
| | | const searchForm = reactive({ |
| | | warehouseName: "", |
| | | location: "", |
| | | managerName: "", |
| | | }); |
| | | |
| | | // å¯¹è¯æ¡ç¸å
³ |
| | | const dialogVisible = ref(false); |
| | | const dialogType = ref("add"); // 'add' æ 'edit' |
| | | const dialogTitle = computed(() => |
| | | dialogType.value === "add" ? "æ°å¢ä»åº" : "ç¼è¾ä»åº" |
| | | ); |
| | | const isEdit = computed(() => dialogType.value === "edit"); |
| | | const formRef = ref(); |
| | | |
| | | // è¡¨åæ°æ® |
| | | const formState = reactive({ |
| | | id: undefined, |
| | | warehouseName: "", |
| | | location: "", |
| | | managerId: undefined, |
| | | managerName: "", |
| | | contactPhone: "", |
| | | status: true, |
| | | }); |
| | | |
| | | // ç¨æ·å表 |
| | | const userList = ref([]); |
| | | |
| | | // 表åéªè¯è§å |
| | | const formRules = { |
| | | warehouseName: [ |
| | | { required: true, message: "请è¾å
¥ä»åºåç§°", trigger: "blur" }, |
| | | { min: 1, max: 50, message: "é¿åº¦å¨ 1 å° 50 个å符", trigger: "blur" }, |
| | | ], |
| | | location: [ |
| | | { required: true, message: "请è¾å
¥ä»åºä½ç½®", trigger: "blur" }, |
| | | { min: 1, max: 200, message: "é¿åº¦å¨ 1 å° 200 个å符", trigger: "blur" }, |
| | | ], |
| | | managerId: [ |
| | | { required: true, message: "è¯·éæ©è´è´£äºº", trigger: "change" }, |
| | | ], |
| | | contactPhone: [ |
| | | { required: true, message: "请è¾å
¥èç³»çµè¯", trigger: "blur" }, |
| | | { pattern: /^1[3-9]\d{9}$|^0\d{2,3}-?\d{7,8}$/, message: "请è¾å
¥æ£ç¡®ççµè¯å·ç ", trigger: "blur" }, |
| | | ], |
| | | status: [{ required: true, message: "è¯·éæ©ç¶æ", trigger: "change" }], |
| | | }; |
| | | |
| | | // è·åç¨æ·å表 |
| | | const getUserList = () => { |
| | | listUser({ pageNum: 1, pageSize: 1000 }).then((res) => { |
| | | userList.value = res.rows || []; |
| | | }); |
| | | }; |
| | | |
| | | // è´è´£äººéæ©åå |
| | | const handleManagerChange = (userId) => { |
| | | const user = userList.value.find((item) => item.userId === userId); |
| | | if (user) { |
| | | formState.managerName = user.nickName; |
| | | } else { |
| | | formState.managerName = ""; |
| | | } |
| | | }; |
| | | |
| | | // æ¥è¯¢å表 |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | // éç½®æç´¢ |
| | | const handleReset = () => { |
| | | searchForm.warehouseName = ""; |
| | | searchForm.location = ""; |
| | | searchForm.managerName = ""; |
| | | handleQuery(); |
| | | }; |
| | | |
| | | const paginationChange = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | getWarehousePage({ |
| | | ...searchForm, |
| | | current: page.current, |
| | | size: page.size, |
| | | }) |
| | | .then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records || []; |
| | | total.value = res.data.total || 0; |
| | | }) |
| | | .catch(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // æ°å¢ |
| | | const handleAdd = () => { |
| | | dialogType.value = "add"; |
| | | resetForm(); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // ç¼è¾ |
| | | const handleEdit = (row) => { |
| | | dialogType.value = "edit"; |
| | | resetForm(); |
| | | // æ ¹æ®managerNameæ¥æ¾å¯¹åºçmanagerId |
| | | const user = userList.value.find((item) => item.nickName === row.managerName); |
| | | // å¡«å
è¡¨åæ°æ® |
| | | Object.assign(formState, { |
| | | id: row.id, |
| | | warehouseName: row.warehouseName, |
| | | location: row.location, |
| | | managerId: user ? user.userId : row.managerId, |
| | | managerName: row.managerName, |
| | | contactPhone: row.contactPhone, |
| | | status: row.status, |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // é置表å |
| | | const resetForm = () => { |
| | | formState.id = undefined; |
| | | formState.warehouseName = ""; |
| | | formState.location = ""; |
| | | formState.managerId = undefined; |
| | | formState.managerName = ""; |
| | | formState.contactPhone = ""; |
| | | formState.status = true; |
| | | proxy.$refs["formRef"]?.resetFields(); |
| | | }; |
| | | |
| | | // å
³éå¯¹è¯æ¡ |
| | | const closeDialog = () => { |
| | | dialogVisible.value = false; |
| | | resetForm(); |
| | | }; |
| | | |
| | | // æäº¤è¡¨å |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate((valid) => { |
| | | if (valid) { |
| | | if (dialogType.value === "add") { |
| | | submitAdd(); |
| | | } else { |
| | | submitEdit(); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // æäº¤æ°å¢ |
| | | const submitAdd = () => { |
| | | const params = { ...formState }; |
| | | delete params.id; |
| | | addWarehouse(params) |
| | | .then(() => { |
| | | ElMessage.success("æ°å¢æå"); |
| | | closeDialog(); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("æ°å¢å¤±è´¥"); |
| | | }); |
| | | }; |
| | | |
| | | // æäº¤ç¼è¾ |
| | | const submitEdit = () => { |
| | | const params = { ...formState }; |
| | | updateWarehouse(params) |
| | | .then(() => { |
| | | ElMessage.success("ç¼è¾æå"); |
| | | closeDialog(); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("ç¼è¾å¤±è´¥"); |
| | | }); |
| | | }; |
| | | |
| | | // ç¶æåæ´ |
| | | const handleStatusChange = (row) => { |
| | | const statusText = row.status ? "å¯ç¨" : "åç¨"; |
| | | ElMessageBox.confirm( |
| | | `确认è¦${statusText}该ä»åºåï¼`, |
| | | "æç¤º", |
| | | { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | } |
| | | ) |
| | | .then(() => { |
| | | updateWarehouseStatus(row.id, row.status) |
| | | .then(() => { |
| | | ElMessage.success(`${statusText}æå`); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | // æ¢å¤åç¶æ |
| | | row.status = !row.status; |
| | | ElMessage.error(`${statusText}失败`); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | // æ¢å¤åç¶æ |
| | | row.status = !row.status; |
| | | ElMessage.info("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // æ¹éå é¤ |
| | | const handleDelete = () => { |
| | | if (selectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning("è¯·éæ©è¦å é¤çæ°æ®"); |
| | | return; |
| | | } |
| | | const ids = selectedRows.value.map((item) => item.id); |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | delWarehouse(ids).then(() => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // åè¡å é¤ |
| | | const handleRowDelete = (row) => { |
| | | ElMessageBox.confirm("确认å é¤è¯¥ä»åºåï¼", "æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | delWarehouse([row.id]).then(() => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | // åå§åå è½½æ°æ® |
| | | onMounted(() => { |
| | | getList(); |
| | | getUserList(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .search_form { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | gap: 10px; |
| | | } |
| | | .search_title { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | } |
| | | .ml10 { |
| | | margin-left: 10px; |
| | | } |
| | | .table_list { |
| | | margin-top: 10px; |
| | | } |
| | | </style> |
| | |
| | | prop="taxExclusiveTotalPrice" |
| | | :formatter="formattedNumber" |
| | | width="150" /> |
| | | <el-table-column label="æ¯å¦è´¨æ£" |
| | | prop="isChecked" |
| | | width="150"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.isChecked ? 'success' : 'info'"> |
| | | {{ scope.row.isChecked ? 'æ¯' : 'å¦' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" |
| | | label="æä½" |
| | | min-width="60" |
| | |
| | | :min="0" |
| | | clearable |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯å¦è´¨æ£ï¼" |
| | | prop="isChecked"> |
| | | <el-radio-group v-model="productForm.isChecked"> |
| | | <el-radio label="æ¯" |
| | | :value="true" /> |
| | | <el-radio label="å¦" |
| | | :value="false" /> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | supplierId: "", |
| | | paymentMethod: "", |
| | | executionDate: "", |
| | | isChecked: false, |
| | | }, |
| | | rules: { |
| | | purchaseContractNumber: [ |
| | |
| | | taxExclusiveTotalPrice: "", |
| | | invoiceType: "", |
| | | warnNum: "", |
| | | isChecked: false, |
| | | }, |
| | | productRules: { |
| | | productId: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | | invoiceType: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | isChecked: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { productForm, productRules } = toRefs(productFormData); |
| | |
| | | // çå¾
DOM æ´æ° |
| | | await nextTick(); |
| | | |
| | | if (type === "add") { |
| | | productForm.value.isChecked = false; |
| | | } |
| | | |
| | | |
| | | if (type === "edit") { |
| | | // å¤å¶è¡æ°æ® |
| | |
| | | <el-table-column label="ä¸å«ç¨æ»ä»·(å
)" |
| | | prop="taxExclusiveTotalPrice" |
| | | :formatter="formattedNumber" /> |
| | | <el-table-column label="æ¯å¦ç产" |
| | | prop="isProduction" |
| | | width="150"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.isProduction ? 'success' : 'info'"> |
| | | {{ scope.row.isProduction ? 'æ¯' : 'å¦' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" |
| | | label="æä½" |
| | | min-width="60" |
| | |
| | | <el-option label="å¢ä¸ç¥¨" |
| | | value="å¢ä¸ç¥¨" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯å¦ç产ï¼" |
| | | prop="isProduction"> |
| | | <el-radio-group v-model="productForm.isProduction"> |
| | | <el-radio label="æ¯" |
| | | :value="true" /> |
| | | <el-radio label="å¦" |
| | | :value="false" /> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | taxInclusiveTotalPrice: "", |
| | | taxExclusiveTotalPrice: "", |
| | | invoiceType: "", |
| | | isProduction: false, |
| | | }, |
| | | productRules: { |
| | | productCategory: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | |
| | | { required: true, message: "请è¾å
¥", trigger: "blur" }, |
| | | ], |
| | | invoiceType: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | isProduction: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | }, |
| | | }); |
| | | const { productForm, productRules } = toRefs(productFormData); |
| | |
| | | |
| | | productOperationType.value = type; |
| | | productForm.value = {}; |
| | | if (type === "add") { |
| | | productForm.value.isProduction = true; |
| | | } |
| | | proxy.resetForm("productFormRef"); |
| | | if (type === "edit") { |
| | | productForm.value = { ...row }; |