feat: 库存管理三表单与详情页签分组、采购台账分栏、油品联动与电话校验、冻结解冻修复
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // å页æ¥è¯¢æ²¹åºä¿¡æ¯å表 |
| | | export function listOilDepot(query) { |
| | | return request({ |
| | | url: '/basic/oilDepot/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å
¨é¨æ²¹åºä¿¡æ¯ï¼ä¾ä¸æéæ©ï¼ |
| | | export function allOilDepot() { |
| | | return request({ |
| | | url: '/basic/oilDepot/all', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢æ²¹åºä¿¡æ¯è¯¦æ
|
| | | export function getOilDepot(id) { |
| | | return request({ |
| | | url: '/basic/oilDepot/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢æ²¹åºä¿¡æ¯ |
| | | export function addOilDepot(data) { |
| | | return request({ |
| | | url: '/basic/oilDepot/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹æ²¹åºä¿¡æ¯ |
| | | export function updateOilDepot(data) { |
| | | return request({ |
| | | url: '/basic/oilDepot/update', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å 餿²¹åºä¿¡æ¯ |
| | | export function delOilDepot(ids) { |
| | | return request({ |
| | | url: '/basic/oilDepot/del', |
| | | method: 'delete', |
| | | data: ids |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // å页æ¥è¯¢å¨ç½ä¿¡æ¯å表 |
| | | export function listTankInfo(query) { |
| | | return request({ |
| | | url: '/basic/tankInfo/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å
¨é¨å¨ç½ä¿¡æ¯ï¼ä¾ä¸æéæ©ï¼ |
| | | export function allTankInfo() { |
| | | return request({ |
| | | url: '/basic/tankInfo/all', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å¨ç½ä¿¡æ¯è¯¦æ
|
| | | export function getTankInfo(id) { |
| | | return request({ |
| | | url: '/basic/tankInfo/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢å¨ç½ä¿¡æ¯ |
| | | export function addTankInfo(data) { |
| | | return request({ |
| | | url: '/basic/tankInfo/add', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹å¨ç½ä¿¡æ¯ |
| | | export function updateTankInfo(data) { |
| | | return request({ |
| | | url: '/basic/tankInfo/update', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤å¨ç½ä¿¡æ¯ |
| | | export function delTankInfo(ids) { |
| | | return request({ |
| | | url: '/basic/tankInfo/del', |
| | | method: 'delete', |
| | | data: ids |
| | | }) |
| | | } |
| | |
| | | }); |
| | | }; |
| | | |
| | | // æ°å¢æ²¹ååºåºè®°å½ï¼æ²¹ååºåºä¸ç¨è¡¨åï¼ä»
å建记å½ï¼ä¸è°æ´åºåï¼ |
| | | export const addOilOutRecordOnly = (params) => { |
| | | return request({ |
| | | url: "/stockInventory/addOilOutRecordOnly", |
| | | method: "post", |
| | | data: params, |
| | | }); |
| | | }; |
| | | |
| | | export const getStockInventoryReportList = (params) => { |
| | | return request({ |
| | | url: "/stockInventory/stockInventoryPage", |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <el-form :model="searchForm" |
| | | :inline="true"> |
| | | <el-form-item label="æ²¹åºåç§°ï¼"> |
| | | <el-input v-model="searchForm.depotName" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æå±å
¬å¸ï¼"> |
| | | <el-input v-model="searchForm.company" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="handleQuery"> æç´¢ |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;"> |
| | | <el-button type="primary" |
| | | @click="openForm('add')">æ°å¢æ²¹åº</el-button> |
| | | <el-button type="danger" |
| | | plain |
| | | @click="handleDelete">å é¤ |
| | | </el-button> |
| | | </div> |
| | | <el-table :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | @selection-change="handleSelectionChange"> |
| | | <el-table-column align="center" |
| | | type="selection" |
| | | width="55" /> |
| | | <el-table-column align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" /> |
| | | <el-table-column label="æ²¹åºåç§°" |
| | | prop="depotName" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="è´è´£äºº" |
| | | prop="chargePerson" |
| | | width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="èç³»çµè¯" |
| | | prop="phone" |
| | | width="140" /> |
| | | <el-table-column label="å¯ç¨æ¥æ" |
| | | prop="enableDate" |
| | | width="120" /> |
| | | <el-table-column label="æå±å
¬å¸" |
| | | prop="company" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="å建æ¶é´" |
| | | prop="createTime" |
| | | width="180"> |
| | | <template #default="scope"> |
| | | {{ scope.row.createTime ? scope.row.createTime.replace('T', ' ').slice(0, 19) : '--' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" |
| | | label="æä½" |
| | | width="120" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-button link |
| | | type="primary" |
| | | @click="openForm('edit', scope.row)">ç¼è¾ |
| | | </el-button> |
| | | <el-button link |
| | | type="danger" |
| | | @click="handleDelete([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> |
| | | <FormDialog v-model="dialogFormVisible" |
| | | :title="operationType === 'add' ? 'æ°å¢æ²¹åº' : 'ç¼è¾æ²¹åº'" |
| | | :width="'40%'" |
| | | :operation-type="operationType" |
| | | @close="closeDia" |
| | | @confirm="submitForm" |
| | | @cancel="closeDia"> |
| | | <el-form :model="form" |
| | | label-width="120px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ²¹åºåç§°ï¼" |
| | | prop="depotName"> |
| | | <el-input v-model="form.depotName" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è´è´£äººï¼" |
| | | prop="chargePerson"> |
| | | <el-input v-model="form.chargePerson" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯ï¼" |
| | | prop="phone"> |
| | | <el-input v-model="form.phone" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¯ç¨æ¥æï¼" |
| | | prop="enableDate"> |
| | | <el-date-picker style="width: 100%" |
| | | v-model="form.enableDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æå±å
¬å¸ï¼" |
| | | prop="company"> |
| | | <el-input v-model="form.company" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import { ref, reactive, toRefs, getCurrentInstance } from "vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { |
| | | listOilDepot, |
| | | addOilDepot, |
| | | updateOilDepot, |
| | | delOilDepot, |
| | | } from "@/api/basicData/oilDepot.js"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref(""); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | }); |
| | | const total = ref(0); |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | depotName: "", |
| | | company: "", |
| | | }, |
| | | form: { |
| | | id: null, |
| | | depotName: "", |
| | | chargePerson: "", |
| | | phone: "", |
| | | enableDate: "", |
| | | company: "", |
| | | }, |
| | | rules: { |
| | | depotName: [{ required: true, message: "请è¾å
¥æ²¹åºåç§°", trigger: "blur" }], |
| | | company: [{ required: true, message: "请è¾å
¥æå±å
¬å¸", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | listOilDepot({ ...searchForm.value, ...page }) |
| | | .then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records || []; |
| | | total.value = res.data.total || 0; |
| | | }) |
| | | .catch(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | const paginationChange = obj => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | |
| | | const handleSelectionChange = selection => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | const openForm = (type, row) => { |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = true; |
| | | if (type === "edit" && row) { |
| | | const { id, depotName, chargePerson, phone, enableDate, company } = row; |
| | | form.value = { id, depotName, chargePerson, phone, enableDate, company }; |
| | | } |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | const api = form.value.id ? updateOilDepot : addOilDepot; |
| | | api(form.value).then(() => { |
| | | proxy.$modal.msgSuccess("æä½æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | |
| | | const handleDelete = rows => { |
| | | let ids = []; |
| | | if (rows) { |
| | | ids = rows.map(item => item.id); |
| | | } else if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | delOilDepot(ids).then(() => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | getList(); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .search_form { |
| | | margin-bottom: 16px; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <el-form :model="searchForm" |
| | | :inline="true"> |
| | | <el-form-item label="å¨ç½å·ï¼"> |
| | | <el-input v-model="searchForm.tankNo" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="大类ï¼"> |
| | | <el-input v-model="searchForm.category" |
| | | placeholder="请è¾å
¥" |
| | | clearable |
| | | prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="handleQuery"> æç´¢ |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;"> |
| | | <el-button type="primary" |
| | | @click="openForm('add')">æ°å¢å¨ç½</el-button> |
| | | <el-button type="danger" |
| | | plain |
| | | @click="handleDelete()">å é¤ |
| | | </el-button> |
| | | </div> |
| | | <el-table :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | @selection-change="handleSelectionChange"> |
| | | <el-table-column align="center" |
| | | type="selection" |
| | | width="55" /> |
| | | <el-table-column align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" /> |
| | | <el-table-column label="å¨ç½å·" |
| | | prop="tankNo" |
| | | min-width="140" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="大类" |
| | | prop="category" |
| | | min-width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="æ²¹å" |
| | | prop="oilProduct" |
| | | min-width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="ç½å®¹" |
| | | prop="capacity" |
| | | min-width="120" /> |
| | | <el-table-column label="åºåä½é(m³)" |
| | | prop="remaining" |
| | | min-width="140" /> |
| | | <el-table-column label="ç§å®¢ä¿¡æ¯" |
| | | prop="tenantInfo" |
| | | min-width="160" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="å建æ¶é´" |
| | | prop="createTime" |
| | | min-width="180"> |
| | | <template #default="scope"> |
| | | {{ scope.row.createTime ? scope.row.createTime.replace('T', ' ').slice(0, 19) : '--' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" |
| | | label="æä½" |
| | | width="120" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-button link |
| | | type="primary" |
| | | @click="openForm('edit', scope.row)">ç¼è¾ |
| | | </el-button> |
| | | <el-button link |
| | | type="danger" |
| | | @click="handleDelete([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> |
| | | <FormDialog v-model="dialogFormVisible" |
| | | :title="operationType === 'add' ? 'æ°å¢å¨ç½' : 'ç¼è¾å¨ç½'" |
| | | :width="'40%'" |
| | | :operation-type="operationType" |
| | | @close="closeDia" |
| | | @confirm="submitForm" |
| | | @cancel="closeDia"> |
| | | <el-form :model="form" |
| | | label-width="120px" |
| | | label-position="top" |
| | | :rules="rules" |
| | | ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¨ç½å·ï¼" |
| | | prop="tankNo"> |
| | | <el-input v-model="form.tankNo" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="大类ï¼" |
| | | prop="category"> |
| | | <el-input v-model="form.category" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ²¹åï¼" |
| | | prop="oilProduct"> |
| | | <el-select v-model="form.oilProduct" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="æ±½#92" |
| | | value="æ±½#92" /> |
| | | <el-option label="æ±½#95" |
| | | value="æ±½#95" /> |
| | | <el-option label="æ´#0" |
| | | value="æ´#0" /> |
| | | <el-option label="æ´#-35" |
| | | value="æ´#-35" /> |
| | | <el-option label="åæ²¹" |
| | | value="åæ²¹" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç½å®¹ï¼" |
| | | prop="capacity"> |
| | | <el-input-number v-model="form.capacity" |
| | | :precision="2" |
| | | :step="1" |
| | | :min="0" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåä½é(m³)ï¼" |
| | | prop="remaining"> |
| | | <el-input-number v-model="form.remaining" |
| | | :precision="2" |
| | | :step="1" |
| | | :min="0" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç§å®¢ä¿¡æ¯ï¼" |
| | | prop="tenantInfo"> |
| | | <el-input v-model="form.tenantInfo" |
| | | placeholder="请è¾å
¥ç§å®¢ä¿¡æ¯" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import { ref, reactive, toRefs, getCurrentInstance } from "vue"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { |
| | | listTankInfo, |
| | | addTankInfo, |
| | | updateTankInfo, |
| | | delTankInfo, |
| | | } from "@/api/basicData/tankInfo.js"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const dialogFormVisible = ref(false); |
| | | const operationType = ref(""); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | }); |
| | | const total = ref(0); |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | | tankNo: "", |
| | | category: "", |
| | | }, |
| | | form: { |
| | | id: null, |
| | | tankNo: "", |
| | | category: "", |
| | | oilProduct: "", |
| | | capacity: null, |
| | | remaining: null, |
| | | tenantInfo: "", |
| | | }, |
| | | rules: { |
| | | tankNo: [{ required: true, message: "请è¾å
¥å¨ç½å·", trigger: "blur" }], |
| | | category: [{ required: true, message: "请è¾å
¥å¤§ç±»", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | const { searchForm, form, rules } = toRefs(data); |
| | | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | listTankInfo({ ...searchForm.value, ...page }) |
| | | .then(res => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records || []; |
| | | total.value = res.data.total || 0; |
| | | }) |
| | | .catch(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const handleQuery = () => { |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | const paginationChange = obj => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList(); |
| | | }; |
| | | |
| | | const handleSelectionChange = selection => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | const openForm = (type, row) => { |
| | | operationType.value = type; |
| | | form.value = {}; |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = true; |
| | | if (type === "edit" && row) { |
| | | const { id, tankNo, category, oilProduct, capacity, remaining, tenantInfo } = row; |
| | | form.value = { id, tankNo, category, oilProduct, capacity, remaining, tenantInfo }; |
| | | } |
| | | }; |
| | | |
| | | const submitForm = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | const api = form.value.id ? updateTankInfo : addTankInfo; |
| | | api(form.value).then(() => { |
| | | proxy.$modal.msgSuccess("æä½æå"); |
| | | closeDia(); |
| | | getList(); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | |
| | | const handleDelete = rows => { |
| | | let ids = []; |
| | | if (rows) { |
| | | ids = rows.map(item => item.id); |
| | | } else if (selectedRows.value.length > 0) { |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("è¯·éæ©æ°æ®"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("éä¸çå
容å°è¢«å é¤ï¼æ¯å¦ç¡®è®¤å é¤ï¼", "å é¤", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | delTankInfo(ids).then(() => { |
| | | proxy.$modal.msgSuccess("å 餿å"); |
| | | getList(); |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | proxy.$modal.msg("已忶"); |
| | | }); |
| | | }; |
| | | |
| | | getList(); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .search_form { |
| | | margin-bottom: 16px; |
| | | } |
| | | </style> |
| | |
| | | > |
| | | <div class="detail-content"> |
| | | <div class="detail-table-wrapper"> |
| | | <el-tabs v-model="detailTab" |
| | | class="detail-tabs"> |
| | | <el-tab-pane label="åºåä¿¡æ¯" |
| | | name="main"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="å
¥åºä¿¡æ¯" |
| | | name="in"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | style="width: 100%" |
| | | height="100%" |
| | | > |
| | | <el-table-column label="å
¥åºä¿¡æ¯" |
| | | align="center" |
| | | :header-cell-style="groupHeaderStyle"> |
| | | <el-table-column label="æ²¹å" prop="oilProduct" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºåç§°" prop="oilDepotName" min-width="130" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºç±»å«" prop="inboundCategory" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å¨ç½å·" prop="tankNo" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å
¥åºæ¶é´" prop="inboundTime" min-width="160" show-overflow-tooltip /> |
| | | <el-table-column label="ååºåæ°é(å¨)" prop="originalQuantity" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="客æ·åç§°" prop="customerName" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="客æ·å¯¹æ¥äºº" prop="contactPerson" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="对æ¥äººçµè¯" prop="contactPhone" min-width="120" show-overflow-tooltip /> |
| | | </el-table-column> |
| | | <el-table-column label="ç©æµä¿¡æ¯" |
| | | align="center" |
| | | :header-cell-style="groupHeaderStyle"> |
| | | <el-table-column label="叿ºå§å" prop="driverName" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="叿ºçµè¯" prop="driverPhone" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="æ¼è¿åå§å" prop="escortName" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="æ¼è¿åçµè¯" prop="escortPhone" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="车çå·" prop="truckPlateNo" min-width="110" show-overflow-tooltip /> |
| | | <el-table-column label="车æçå·" prop="trailerPlateNo" min-width="110" show-overflow-tooltip /> |
| | | </el-table-column> |
| | | <el-table-column label="叿²¹æä½ä¿¡æ¯" |
| | | align="center" |
| | | :header-cell-style="groupHeaderStyle"> |
| | | <el-table-column label="车ä½/é
å°æ£éª" prop="tankInspectionStatus" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="å¸è½¦é¹¤ä½" prop="unloadingCranePosition" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å¯åº¦" prop="density" min-width="80" show-overflow-tooltip /> |
| | | <el-table-column label="叿²¹æç
§" prop="unloadPhotos" align="center" min-width="90"> |
| | | <template #default="scope"> |
| | | <el-image |
| | | v-if="toPhotoArray(scope.row.unloadPhotos).length" |
| | | :src="getPhotoUrl(toPhotoArray(scope.row.unloadPhotos)[0])" |
| | | :preview-src-list="getPhotoUrls(scope.row.unloadPhotos)" |
| | | preview-teleported |
| | | fit="cover" |
| | | style="width: 40px; height: 40px; border-radius: 4px" |
| | | /> |
| | | <span v-else>--</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column label="è¿ç£
æ°æ®" |
| | | align="center" |
| | | :header-cell-style="groupHeaderStyle"> |
| | | <el-table-column label="æ¯é(å¨)" prop="grossWeight" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="ç®é(å¨)" prop="tareWeight" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="åé(å¨)" prop="netWeight" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="äºé(å¨)" prop="lossQuantity" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="å®é
å
¥åºä½ç§¯(å)" prop="actualVolume" min-width="130" show-overflow-tooltip /> |
| | | <el-table-column label="ç£
å" prop="poundPhotos" align="center" min-width="90"> |
| | | <template #default="scope"> |
| | | <el-image |
| | | v-if="toPhotoArray(scope.row.poundPhotos).length" |
| | | :src="getPhotoUrl(toPhotoArray(scope.row.poundPhotos)[0])" |
| | | :preview-src-list="getPhotoUrls(scope.row.poundPhotos)" |
| | | preview-teleported |
| | | fit="cover" |
| | | style="width: 40px; height: 40px; border-radius: 4px" |
| | | /> |
| | | <span v-else>--</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="åºåºä¿¡æ¯" |
| | | name="out"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | style="width: 100%" |
| | | height="100%" |
| | | > |
| | | <el-table-column label="åºåºä¿¡æ¯" |
| | | align="center" |
| | | :header-cell-style="groupHeaderStyle"> |
| | | <el-table-column label="åºåºç±»å«" prop="outCategory" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="å¨åºåç§°" prop="outOilDepotName" min-width="130" show-overflow-tooltip /> |
| | | <el-table-column label="å¨ç½å·" prop="outTankNo" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="åºåºæ¥æ" prop="outDate" min-width="110" show-overflow-tooltip /> |
| | | <el-table-column label="æ²¹å" prop="outOilProduct" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="åºåºå¨ä½(å¨)" prop="outTonnage" min-width="110" show-overflow-tooltip /> |
| | | <el-table-column label="客æ·åç§°" prop="outCustomerName" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="客æ·å¯¹æ¥äºº" prop="outContactPerson" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="对æ¥äººçµè¯" prop="outContactPhone" min-width="120" show-overflow-tooltip /> |
| | | </el-table-column> |
| | | <el-table-column label="è£
æ²¹æä½ä¿¡æ¯" |
| | | align="center" |
| | | :header-cell-style="groupHeaderStyle"> |
| | | <el-table-column label="è£
æ²¹æ£éª" prop="loadingInspectionStatus" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="è£
车鹤ä½" prop="loadingCranePosition" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="å¯åº¦" prop="outDensity" min-width="80" show-overflow-tooltip /> |
| | | <el-table-column label="è£
æ²¹æç
§" prop="loadingPhotos" align="center" min-width="90"> |
| | | <template #default="scope"> |
| | | <el-image |
| | | v-if="toPhotoArray(scope.row.loadingPhotos).length" |
| | | :src="getPhotoUrl(toPhotoArray(scope.row.loadingPhotos)[0])" |
| | | :preview-src-list="getPhotoUrls(scope.row.loadingPhotos)" |
| | | preview-teleported |
| | | fit="cover" |
| | | style="width: 40px; height: 40px; border-radius: 4px" |
| | | /> |
| | | <span v-else>--</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column label="åºåºè¿ç£
æ°æ®" |
| | | align="center" |
| | | :header-cell-style="groupHeaderStyle"> |
| | | <el-table-column label="æ¯é(å¨)" prop="outGrossWeight" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="ç®é(å¨)" prop="outTareWeight" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="åé(å¨)" prop="outNetWeight" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="äºé(å¨)" prop="outLossQuantity" min-width="90" show-overflow-tooltip /> |
| | | <el-table-column label="å®é
å
¥åºä½ç§¯(å)" prop="outActualVolume" min-width="130" show-overflow-tooltip /> |
| | | <el-table-column label="ç£
å" prop="outPoundPhotos" align="center" min-width="90"> |
| | | <template #default="scope"> |
| | | <el-image |
| | | v-if="toPhotoArray(scope.row.outPoundPhotos).length" |
| | | :src="getPhotoUrl(toPhotoArray(scope.row.outPoundPhotos)[0])" |
| | | :preview-src-list="getPhotoUrls(scope.row.outPoundPhotos)" |
| | | preview-teleported |
| | | fit="cover" |
| | | style="width: 40px; height: 40px; border-radius: 4px" |
| | | /> |
| | | <span v-else>--</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> |
| | | <el-table-column label="åºåºç©æµä¿¡æ¯" |
| | | align="center" |
| | | :header-cell-style="groupHeaderStyle"> |
| | | <el-table-column label="叿ºå§å" prop="outDriverName" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="叿ºçµè¯" prop="outDriverPhone" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="æ¼è¿åå§å" prop="outEscortName" min-width="100" show-overflow-tooltip /> |
| | | <el-table-column label="æ¼è¿åçµè¯" prop="outEscortPhone" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="车çå·" prop="outTruckPlateNo" min-width="110" show-overflow-tooltip /> |
| | | <el-table-column label="车æçå·" prop="outTrailerPlateNo" min-width="110" show-overflow-tooltip /> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | <pagination |
| | | v-show="total > 0" |
| | |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const total = ref(0); |
| | | const detailTab = ref("main"); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 20, |
| | |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // å¾çåï¼å端è¿å为 JSON å符串ï¼å
¼å®¹æ°ç»/å符串两ç§å½¢æ |
| | | const toPhotoArray = (value) => { |
| | | if (!value) { |
| | | return []; |
| | | } |
| | | if (Array.isArray(value)) { |
| | | return value; |
| | | } |
| | | if (typeof value === "string") { |
| | | try { |
| | | const parsed = JSON.parse(value); |
| | | return Array.isArray(parsed) ? parsed : []; |
| | | } catch (e) { |
| | | return []; |
| | | } |
| | | } |
| | | return []; |
| | | }; |
| | | |
| | | // å¾çåï¼ååå¼ å°åï¼æ¯æå符串æ {url} å¯¹è±¡ï¼ |
| | | const getPhotoUrl = (photo) => |
| | | typeof photo === "string" ? photo : photo?.url || photo?.previewURL || ""; |
| | | |
| | | // å¾çåï¼åå
¨é¨å°åç¨äºé¢è§ |
| | | const getPhotoUrls = (photos) => |
| | | toPhotoArray(photos).map(getPhotoUrl).filter(Boolean); |
| | | |
| | | // åç»ç¶è¡¨å¤´æ ·å¼ï¼åºåååç±» |
| | | const groupHeaderStyle = { |
| | | background: "#e8f3ff", |
| | | color: "#1d6fd8", |
| | | fontWeight: "700", |
| | | fontSize: "13px", |
| | | }; |
| | | |
| | | const paginationChange = (obj) => { |
| | |
| | | min-height: 0; |
| | | } |
| | | |
| | | .detail-tabs { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | :deep(.detail-tabs .el-tabs__content) { |
| | | flex: 1; |
| | | min-height: 0; |
| | | } |
| | | |
| | | :deep(.detail-tabs .el-tab-pane) { |
| | | height: 100%; |
| | | } |
| | | |
| | | :deep(.batch-no-qty-detail-dialog .el-dialog) { |
| | | max-width: calc(100vw - 48px); |
| | | } |
| | |
| | | :label="operationType === 'frozen' ? 'å»ç»æ°éï¼' : 'è§£å»æ°éï¼'" |
| | | prop="lockedQuantity" |
| | | > |
| | | <el-input-number v-model="formState.lockedQuantity" :step="1" :min="maxCount > 0 ? 1 : 0" precision="0" style="width: 100%" :max="maxCount" :disabled="maxCount < 1" /> |
| | | <el-input-number v-model="formState.lockedQuantity" :step="0.01" :min="0" precision="2" style="width: 100%" :max="maxCount" :disabled="maxCount < 1" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance, onMounted} from "vue"; |
| | | import {ref, computed, watch, getCurrentInstance, onMounted} from "vue"; |
| | | import {frozenStockInventory, thawStockInventory} from "@/api/inventoryManagement/stockInventory.js"; |
| | | import {frozenStockUninventory, thawStockUninventory} from "@/api/inventoryManagement/stockUninventory.js"; |
| | | |
| | |
| | | lockedQuantity: undefined, |
| | | }); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit('update:visible', val); |
| | | }, |
| | | }); |
| | | // å¼¹çªå¼å
³ç¨æ¬å°ç¶æç®¡çï¼ç¶çº§æå¼æ¶åæ¥ä¸º trueï¼æ¬å°å
³éåéç¥ç¶çº§ |
| | | const isShow = ref(false); |
| | | |
| | | watch( |
| | | () => props.visible, |
| | | val => { |
| | | isShow.value = val; |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | |
| | | const requestClose = () => { |
| | | isShow.value = false; |
| | | emit('update:visible', false); |
| | | }; |
| | | |
| | | let { proxy } = getCurrentInstance() |
| | | |
| | |
| | | lockedQuantity: undefined, |
| | | type: undefined, |
| | | }; |
| | | isShow.value = false; |
| | | requestClose(); |
| | | }; |
| | | |
| | | const maxCount = computed(() => { |
| | |
| | | } |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // ä¸ä¾èµè¡¨åå¼ç¨ï¼ç´æ¥æå¨æ ¡éª |
| | | if (!formState.value.type) { |
| | | proxy.$modal.msgError("è¯·éæ©åºåç±»å"); |
| | | return; |
| | | } |
| | | const qty = Number(formState.value.lockedQuantity); |
| | | if (!formState.value.lockedQuantity || qty <= 0) { |
| | | proxy.$modal.msgError( |
| | | `请è¾å
¥${props.operationType === 'frozen' ? 'å»ç»' : 'è§£å»'}æ°é` |
| | | ); |
| | | return; |
| | | } |
| | | if (qty > maxCount.value) { |
| | | proxy.$modal.msgError(`æ°éä¸è½è¶
è¿${maxCount.value}`); |
| | | return; |
| | | } |
| | | |
| | | const data = Object.assign({}, formState.value); |
| | | const doSubmit = (api, id) => { |
| | | data.id = id; |
| | | api(data).then(res => { |
| | | if (res.code === 200) { |
| | | requestClose(); |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | } else { |
| | | proxy.$modal.msgError(res.msg); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | if (formState.value.type === 'qualified') { |
| | | data.id = props.record.qualifiedId; |
| | | // å»ç» |
| | | if (props.operationType === 'frozen') { |
| | | frozenStockInventory(data).then(res => { |
| | | if (res.code === 200) { |
| | | // å
³éæ¨¡ææ¡ |
| | | isShow.value = false; |
| | | // åç¥ç¶ç»ä»¶å·²å®æ |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | doSubmit( |
| | | props.operationType === 'frozen' ? frozenStockInventory : thawStockInventory, |
| | | props.record.qualifiedId |
| | | ); |
| | | } else { |
| | | proxy.$modal.msgError(res.msg); |
| | | doSubmit( |
| | | props.operationType === 'frozen' ? frozenStockUninventory : thawStockUninventory, |
| | | props.record.unQualifiedId |
| | | ); |
| | | } |
| | | }) |
| | | } else { |
| | | thawStockInventory(data).then(res => { |
| | | if (res.code === 200) { |
| | | // å
³éæ¨¡ææ¡ |
| | | isShow.value = false; |
| | | // åç¥ç¶ç»ä»¶å·²å®æ |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | } else { |
| | | proxy.$modal.msgError(res.msg); |
| | | } |
| | | }) |
| | | } |
| | | } else { |
| | | data.id = props.record.unQualifiedId; |
| | | if (props.operationType === 'frozen') { |
| | | frozenStockUninventory(data).then(res => { |
| | | if (res.code === 200) { |
| | | // å
³éæ¨¡ææ¡ |
| | | isShow.value = false; |
| | | // åç¥ç¶ç»ä»¶å·²å®æ |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | } else { |
| | | proxy.$modal.msgError(res.msg); |
| | | } |
| | | }) |
| | | } else { |
| | | thawStockUninventory(data).then(res => { |
| | | if (res.code === 200) { |
| | | // å
³éæ¨¡ææ¡ |
| | | isShow.value = false; |
| | | // åç¥ç¶ç»ä»¶å·²å®æ |
| | | emit('completed'); |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | } else { |
| | | proxy.$modal.msgError(res.msg); |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | }; |
| | | |
| | | onMounted(() => { |
| | |
| | | <div> |
| | | <el-dialog v-model="isShow" |
| | | title="æ°å¢åºå" |
| | | width="800" |
| | | width="60%" |
| | | @close="closeModal"> |
| | | <el-form label-width="140px" |
| | | :model="formState" |
| | | label-position="top" |
| | | ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="产ååç§°" |
| | | prop="productModelId" |
| | | :rules="[ |
| | |
| | | {{ formState.productName ? formState.productName : 'éæ©äº§å' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼" |
| | | prop="productModelName"> |
| | | <el-input v-model="formState.productModelName" |
| | | disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½" |
| | | prop="unit"> |
| | | <el-input v-model="formState.unit" |
| | | disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåç±»å" |
| | | prop="type" |
| | | :rules="[ |
| | |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.type" |
| | | placeholder="è¯·éæ©åºåç±»å"> |
| | | placeholder="è¯·éæ©åºåç±»å" |
| | | style="width: 100%"> |
| | | <el-option label="åæ ¼åºå" |
| | | value="qualified" /> |
| | | <el-option label="ä¸åæ ¼åºå" |
| | | value="unqualified" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåæ°é" |
| | | prop="qualitity"> |
| | | <el-input-number v-model="formState.qualitity" |
| | |
| | | :precision="2" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¹å·" |
| | | prop="batchNo"> |
| | | <el-input v-model="formState.batchNo" |
| | | placeholder="请è¾å
¥æ¹å·" /> |
| | | </el-form-item> |
| | | <el-form-item v-if="formState.type === 'qualified'" |
| | | label="åºåé¢è¦æ°é" |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col v-if="formState.type === 'qualified'" |
| | | :span="12"> |
| | | <el-form-item label="åºåé¢è¦æ°é" |
| | | prop="warnNum"> |
| | | <el-input-number v-model="formState.warnNum" |
| | | :step="0.01" |
| | |
| | | :precision="2" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="formState.type === 'qualified' ? 12 : 24"> |
| | | <el-form-item label="æ¹å·" |
| | | prop="batchNo"> |
| | | <el-input v-model="formState.batchNo" |
| | | placeholder="请è¾å
¥æ¹å·" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="夿³¨" |
| | | prop="remark"> |
| | | <el-input v-model="formState.remark" |
| | | type="textarea" /> |
| | | type="textarea" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <!-- 产åéæ©å¼¹çª --> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | |
| | | |
| | | const emit = defineEmits(["update:visible", "completed"]); |
| | | |
| | | // ååºå¼æ°æ®ï¼æ¿ä»£é项å¼ç dataï¼ |
| | | const formState = ref({ |
| | | const buildEmptyForm = () => ({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | |
| | | warnNum: 0, |
| | | remark: "", |
| | | }); |
| | | |
| | | const formState = ref(buildEmptyForm()); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | const closeModal = () => { |
| | | // éç½®è¡¨åæ°æ® |
| | | formState.value = { |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | type: undefined, |
| | | qualitity: 0, |
| | | batchNo: null, |
| | | warnNum: 0, |
| | | remark: "", |
| | | }; |
| | | proxy.resetForm("formRef"); |
| | | formState.value = buildEmptyForm(); |
| | | isShow.value = false; |
| | | }; |
| | | |
| | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | // éªè¯æ¯å¦éæ©äºäº§ååè§æ ¼ |
| | | // éªè¯æ¯å¦éæ©äºäº§å |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("è¯·éæ©äº§å"); |
| | | return; |
| | | } |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("è¯·éæ©è§æ ¼"); |
| | | return; |
| | | } |
| | | if (formState.value.type === "qualified") { |
| | | addStockInRecordOnly(formState.value).then(res => { |
| | | // å
³éæ¨¡ææ¡ |
| | | isShow.value = false; |
| | | // åç¥ç¶ç»ä»¶å·²å®æ |
| | | emit("completed"); |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | }); |
| | | } else { |
| | | formState.value.warnNum = 0; |
| | | createStockUnInventory(formState.value).then(res => { |
| | | // å
³éæ¨¡ææ¡ |
| | | isShow.value = false; |
| | | // åç¥ç¶ç»ä»¶å·²å®æ |
| | | emit("completed"); |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | }); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog v-model="isShow" |
| | | title="æ°å¢æ²¹åå
¥åº" |
| | | width="60%" |
| | | @close="closeModal"> |
| | | <el-form label-width="140px" |
| | | :model="formState" |
| | | label-position="top" |
| | | ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="产ååç§°" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©äº§å', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-button type="primary" |
| | | @click="showProductSelectDialog = true"> |
| | | {{ formState.productName ? formState.productName : 'éæ©äº§å' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼" |
| | | prop="productModelName"> |
| | | <el-input v-model="formState.productModelName" |
| | | disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½" |
| | | prop="unit"> |
| | | <el-input v-model="formState.unit" |
| | | disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">å
¥åºä¿¡æ¯</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºåç§°" |
| | | prop="oilDepotId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©å
¥åºåç§°', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.oilDepotId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | popper-class="oil-depot-select-popper" |
| | | style="width: 100%"> |
| | | <el-option v-for="item in oilDepotList" |
| | | :key="item.id" |
| | | :label="item.depotName" |
| | | :value="item.id"> |
| | | <div class="oil-depot-option"> |
| | | <div class="oil-depot-option-title">{{ item.depotName }}</div> |
| | | <div class="oil-depot-option-line">è´è´£äººï¼{{ item.chargePerson }}</div> |
| | | <div class="oil-depot-option-line">èç³»çµè¯ï¼{{ item.phone }}</div> |
| | | <div class="oil-depot-option-line">æå±å
¬å¸ï¼{{ item.company }}</div> |
| | | <div class="oil-depot-option-line">å¯ç¨æ¥æï¼{{ item.enableDate }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºç±»å«" |
| | | prop="inboundCategory" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©å
¥åºç±»å«', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.inboundCategory" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="èªè´å
¥åº" |
| | | value="èªè´å
¥åº" /> |
| | | <el-option label="代å¨å
¥åº" |
| | | value="代å¨å
¥åº" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¨ç½å·" |
| | | prop="tankId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©å¨ç½å·', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.tankId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | popper-class="tank-select-popper" |
| | | style="width: 100%"> |
| | | <el-option v-for="item in tankList" |
| | | :key="item.id" |
| | | :label="item.tankNo" |
| | | :value="item.id"> |
| | | <div class="tank-option"> |
| | | <div class="tank-option-title">{{ item.tankNo }}</div> |
| | | <div class="tank-option-line">大类ï¼{{ item.category }}</div> |
| | | <div class="tank-option-line">æ²¹åï¼{{ item.oilProduct }}</div> |
| | | <div class="tank-option-line">ç½å®¹ï¼{{ item.capacity }}</div> |
| | | <div class="tank-option-line">åºåä½é(m³)ï¼{{ item.remaining }}</div> |
| | | <div class="tank-option-line">ç§å®¢ä¿¡æ¯ï¼{{ item.tenantInfo || '--' }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¥åºæ¶é´" |
| | | prop="inboundTime" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©å
¥åºæ¶é´', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-date-picker v-model="formState.inboundTime" |
| | | type="datetime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | placeholder="è¯·éæ©" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ²¹å" |
| | | prop="oilProduct" |
| | | :rules="isOilProduct ? [ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©æ²¹å', |
| | | trigger: 'change', |
| | | } |
| | | ] : []"> |
| | | <el-input v-if="isOilProduct" |
| | | :model-value="formState.oilProduct" |
| | | readonly |
| | | placeholder="--" /> |
| | | <el-select v-else |
| | | v-model="formState.oilProduct" |
| | | placeholder="è¯·éæ©" |
| | | disabled |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ååºåæ°é(å¨)" |
| | | prop="originalQuantity" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请è¾å
¥ååºåæ°é', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-input-number v-model="formState.originalQuantity" |
| | | :precision="2" |
| | | :step="1" |
| | | :min="0" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="客æ·åç§°" |
| | | prop="customerId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©å®¢æ·åç§°', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-select v-model="formState.customerId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | filterable |
| | | popper-class="customer-select-popper" |
| | | style="width: 100%" |
| | | @change="customerChange"> |
| | | <el-option v-for="item in customerList" |
| | | :key="item.id" |
| | | :label="item.customerName" |
| | | :value="item.id"> |
| | | <div class="customer-option"> |
| | | <div class="customer-option-title">{{ item.customerName }}</div> |
| | | <div class="customer-option-line">弿·è¡åç§°ï¼{{ item.basicBankAccount }}</div> |
| | | <div class="customer-option-line">é¶è¡è´¦æ·ï¼{{ item.bankAccount }}</div> |
| | | <div class="customer-option-line">å°åï¼{{ item.addressPhone }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="客æ·å¯¹æ¥äºº" |
| | | prop="contactPerson" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请è¾å
¥å®¢æ·å¯¹æ¥äºº', |
| | | trigger: 'blur', |
| | | } |
| | | ]"> |
| | | <el-input v-model="formState.contactPerson" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="对æ¥äººçµè¯" |
| | | prop="contactPhone" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请è¾å
¥å¯¹æ¥äººçµè¯', |
| | | trigger: 'blur', |
| | | }, |
| | | { |
| | | pattern: /^1[3-9]\d{9}$/, |
| | | message: '请è¾å
¥ææç11使æºå·ç ', |
| | | trigger: 'blur', |
| | | } |
| | | ]"> |
| | | <el-input v-model="formState.contactPhone" |
| | | placeholder="请è¾å
¥11使°å" |
| | | maxlength="11" |
| | | @input="phoneInput('contactPhone')" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">ç©æµä¿¡æ¯</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="叿ºå§å" |
| | | prop="driverName" |
| | | :rules="[{ required: true, message: '请è¾å
¥å¸æºå§å', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.driverName" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="叿ºçµè¯" |
| | | prop="driverPhone" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥å¸æºçµè¯', trigger: 'blur' }, |
| | | { pattern: /^1[3-9]\d{9}$/, message: '请è¾å
¥ææç11使æºå·ç ', trigger: 'blur' } |
| | | ]"> |
| | | <el-input v-model="formState.driverPhone" |
| | | placeholder="请è¾å
¥11使°å" |
| | | maxlength="11" |
| | | @input="phoneInput('driverPhone')" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¼è¿åå§å" |
| | | prop="escortName" |
| | | :rules="[{ required: true, message: '请è¾å
¥æ¼è¿åå§å', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.escortName" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¼è¿åçµè¯" |
| | | prop="escortPhone" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥æ¼è¿åçµè¯', trigger: 'blur' }, |
| | | { pattern: /^1[3-9]\d{9}$/, message: '请è¾å
¥ææç11使æºå·ç ', trigger: 'blur' } |
| | | ]"> |
| | | <el-input v-model="formState.escortPhone" |
| | | placeholder="请è¾å
¥11使°å" |
| | | maxlength="11" |
| | | @input="phoneInput('escortPhone')" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="车çå·" |
| | | prop="truckPlateNo" |
| | | :rules="[{ required: true, message: '请è¾å
¥è½¦çå·', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.truckPlateNo" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="车æçå·" |
| | | prop="trailerPlateNo" |
| | | :rules="[{ required: true, message: '请è¾å
¥è½¦æçå·', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.trailerPlateNo" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">叿²¹æä½ä¿¡æ¯</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="车ä½/é
å°æ£éªæ¯å¦æ£å¸¸" |
| | | prop="tankInspectionStatus" |
| | | :rules="[{ required: true, message: 'è¯·éæ©è½¦ä½/é
å°æ£éªæ¯å¦æ£å¸¸', trigger: 'change' }]"> |
| | | <el-radio-group v-model="formState.tankInspectionStatus"> |
| | | <el-radio value="æ£å¸¸">æ£å¸¸</el-radio> |
| | | <el-radio value="å¼å¸¸">å¼å¸¸</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å¸è½¦é¹¤ä½" |
| | | prop="unloadingCranePosition" |
| | | :rules="[{ required: true, message: 'è¯·éæ©å¸è½¦é¹¤ä½', trigger: 'change' }]"> |
| | | <el-select v-model="formState.unloadingCranePosition" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="1#æ¬è£
" |
| | | value="1#æ¬è£
" /> |
| | | <el-option label="2#æ¬è£
" |
| | | value="2#æ¬è£
" /> |
| | | <el-option label="ä¸´æ¶æ³µ" |
| | | value="ä¸´æ¶æ³µ" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å¯åº¦" |
| | | prop="density" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥å¯åº¦', trigger: 'blur' }, |
| | | { pattern: /^\d+(\.\d{1,2})?$/, message: '请è¾å
¥æ°åï¼æå¤ä¿ç两ä½å°æ°', trigger: 'blur' }, |
| | | ]"> |
| | | <el-input v-model="formState.density" |
| | | placeholder="请è¾å
¥æ°åï¼æå¤ä¿ç两ä½å°æ°" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="叿²¹å
³é®ç¯èä¸è½¦è¾å
³é®ä½ç½®æç
§" |
| | | prop="unloadPhotos" |
| | | :rules="[{ required: true, message: '请ä¸ä¼ 叿²¹å
³é®ç¯èä¸è½¦è¾å
³é®ä½ç½®æç
§', trigger: 'change' }]"> |
| | | <ImageUpload v-model:file-list="formState.unloadPhotos" |
| | | :limit="10" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">è¿ç£
æ°æ®</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯é(å¨)" |
| | | prop="grossWeight" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥æ¯é', trigger: 'blur' }, |
| | | { pattern: /^\d+$/, message: 'åªè½è¾å
¥æ´æ°æ°å', trigger: 'blur' }, |
| | | ]"> |
| | | <el-input v-model="formState.grossWeight" |
| | | placeholder="请è¾å
¥æ´æ°æ°å" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç®é(å¨)" |
| | | prop="tareWeight" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥ç®é', trigger: 'blur' }, |
| | | { pattern: /^\d+$/, message: 'åªè½è¾å
¥æ´æ°æ°å', trigger: 'blur' }, |
| | | ]"> |
| | | <el-input v-model="formState.tareWeight" |
| | | placeholder="请è¾å
¥æ´æ°æ°å" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="åé(å¨)"> |
| | | <el-input :model-value="netWeight === null ? '--' : netWeight" |
| | | readonly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="äºé(å¨)"> |
| | | <el-input :model-value="lossQuantity === null ? '--' : lossQuantity" |
| | | readonly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å®é
å
¥åºä½ç§¯(å)"> |
| | | <el-input :model-value="actualVolume" |
| | | readonly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç£
åä¸ä¼ " |
| | | prop="poundPhotos" |
| | | :rules="[{ required: true, message: '请ä¸ä¼ ç£
å', trigger: 'change' }]"> |
| | | <ImageUpload v-model:file-list="formState.poundPhotos" |
| | | :limit="10" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <!-- 产åéæ©å¼¹çª --> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" |
| | | @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeModal">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance, onMounted } from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import ImageUpload from "@/components/AttachmentUpload/image/index.vue"; |
| | | import { addStockInRecordOnly } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import { allOilDepot } from "@/api/basicData/oilDepot.js"; |
| | | import { allTankInfo } from "@/api/basicData/tankInfo.js"; |
| | | import { listCustomer } from "@/api/basicData/customer.js"; |
| | | import { productTreeList } from "@/api/basicData/product.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits(["update:visible", "completed"]); |
| | | |
| | | const buildEmptyForm = () => ({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | oilDepotId: undefined, |
| | | inboundCategory: undefined, |
| | | tankId: undefined, |
| | | inboundTime: "", |
| | | oilProduct: undefined, |
| | | originalQuantity: undefined, |
| | | customerId: undefined, |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | driverName: "", |
| | | driverPhone: "", |
| | | escortName: "", |
| | | escortPhone: "", |
| | | truckPlateNo: "", |
| | | trailerPlateNo: "", |
| | | tankInspectionStatus: undefined, |
| | | unloadingCranePosition: undefined, |
| | | density: undefined, |
| | | unloadPhotos: [], |
| | | grossWeight: undefined, |
| | | tareWeight: undefined, |
| | | poundPhotos: [], |
| | | }); |
| | | |
| | | const formState = ref(buildEmptyForm()); |
| | | |
| | | const oilDepotList = ref([]); |
| | | const tankList = ref([]); |
| | | const customerList = ref([]); |
| | | const oilProductOptions = ref([]); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit("update:visible", val); |
| | | }, |
| | | }); |
| | | |
| | | // å¨äº§åæ 䏿¥æ¾"æ²¹å"åç±»èç¹ |
| | | const findOilNode = nodes => { |
| | | for (const node of nodes || []) { |
| | | if (node.productName === "æ²¹å") { |
| | | return node; |
| | | } |
| | | if (node.children && node.children.length) { |
| | | const found = findOilNode(node.children); |
| | | if (found) { |
| | | return found; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | // æéåååç§°å½ä¸çæ²¹åéé¡¹ï¼æ²¹åèç¹åé¡¹ï¼æ¥èªäº§åç»´æ¤æ¨¡åï¼ |
| | | const matchedOilOption = computed(() => |
| | | oilProductOptions.value.find( |
| | | item => item.productName === formState.value.productName |
| | | ) |
| | | ); |
| | | |
| | | // åªæé䏿²¹ååæ®µé项éæçå
·ä½æ²¹åæå¯ç¨æ²¹ååæ®µï¼"æ²¹å"大类æ¬èº«ä¸å¯ç¨ |
| | | const isOilProduct = computed(() => !!matchedOilOption.value); |
| | | |
| | | // åé(å¨) = æ¯é - ç®é |
| | | const netWeight = computed(() => { |
| | | const g = formState.value.grossWeight; |
| | | const t = formState.value.tareWeight; |
| | | if ([g, t].some(v => v === null || v === undefined || v === "")) { |
| | | return null; |
| | | } |
| | | return Number(g) - Number(t); |
| | | }); |
| | | |
| | | // äºé(å¨) = åéçè´æ° |
| | | const lossQuantity = computed(() => { |
| | | if (netWeight.value === null) { |
| | | return null; |
| | | } |
| | | return -netWeight.value; |
| | | }); |
| | | |
| | | // å®é
å
¥åºä½ç§¯(å) = å®é
åé(kg) ÷ å¯åº¦(kg/L)ï¼åéå¨ Ã 1000 转 kg |
| | | const actualVolume = computed(() => { |
| | | const d = formState.value.density; |
| | | if (netWeight.value === null || d === null || d === undefined || d === "" || Number(d) <= 0) { |
| | | return 0; |
| | | } |
| | | return Math.round(((netWeight.value * 1000) / Number(d)) * 100) / 100; |
| | | }); |
| | | |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | const closeModal = () => { |
| | | proxy.resetForm("formRef"); |
| | | formState.value = buildEmptyForm(); |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | // çµè¯è¾å
¥éå¶ï¼åªå
许æ°åï¼æå¤11ä½ |
| | | const phoneInput = field => { |
| | | formState.value[field] = String(formState.value[field] ?? "") |
| | | .replace(/\D/g, "") |
| | | .slice(0, 11); |
| | | }; |
| | | |
| | | // 客æ·éæ©æ¹åï¼ç»å®å®¢æ·ä¿¡æ¯è¡¨ï¼èªå¨å¸¦åºå¯¹æ¥äººä¸å¯¹æ¥çµè¯ |
| | | const customerChange = id => { |
| | | const customer = customerList.value.find(item => item.id === id); |
| | | if (customer) { |
| | | formState.value.contactPerson = customer.contactPerson || ""; |
| | | formState.value.contactPhone = customer.contactPhone || ""; |
| | | } else { |
| | | formState.value.contactPerson = ""; |
| | | formState.value.contactPhone = ""; |
| | | } |
| | | }; |
| | | |
| | | // 产åéæ©å¤ç |
| | | 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; |
| | | // æ²¹åé项ä¸åååç§°åæ¥ï¼å½ä¸æ²¹åé项åèªå¨å¸¦åºè¯¥æ²¹åï¼æªå½ä¸åæ¸
空并ç¦ç¨ |
| | | formState.value.oilProduct = matchedOilOption.value |
| | | ? product.productName |
| | | : undefined; |
| | | showProductSelectDialog.value = false; |
| | | // 触å表åéªè¯æ´æ° |
| | | proxy.$refs["formRef"]?.validateField("productModelId"); |
| | | } |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("è¯·éæ©äº§å"); |
| | | return; |
| | | } |
| | | // 计ç®ç»æé表åæäº¤ï¼æ²¹åå
¥åºåºå®ä¸ºåæ ¼åºåï¼åºåæ°éååé |
| | | formState.value.type = "qualified"; |
| | | formState.value.warnNum = 0; |
| | | formState.value.qualitity = netWeight.value; |
| | | formState.value.netWeight = netWeight.value; |
| | | formState.value.lossQuantity = lossQuantity.value; |
| | | formState.value.actualVolume = actualVolume.value; |
| | | |
| | | addStockInRecordOnly(formState.value).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeModal(); |
| | | emit("completed"); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | allOilDepot().then(res => { |
| | | oilDepotList.value = res?.data || []; |
| | | }); |
| | | allTankInfo().then(res => { |
| | | tankList.value = res?.data || []; |
| | | }); |
| | | listCustomer({ current: 1, size: 1000, type: 0 }).then(res => { |
| | | customerList.value = res?.data?.records || []; |
| | | }); |
| | | productTreeList().then(res => { |
| | | const oilNode = findOilNode(res); |
| | | oilProductOptions.value = oilNode?.children || []; |
| | | }); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | // 表ååæ æ é¢ï¼èè²ç«æ¡ + æµ
èåºè²ï¼çªåºååº |
| | | .form-section-title { |
| | | margin: 18px 0 14px; |
| | | padding: 8px 14px; |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | color: #1d6fd8; |
| | | background: linear-gradient(90deg, rgba(64, 158, 255, 0.14), rgba(64, 158, 255, 0.02)); |
| | | border-left: 4px solid #409eff; |
| | | border-radius: 3px; |
| | | } |
| | | |
| | | // å
¥åºåç§°ä¸æé项ï¼å°å¡çæ ·å¼ |
| | | .oil-depot-option { |
| | | padding: 8px 10px; |
| | | |
| | | .oil-depot-option-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .oil-depot-option-line { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | |
| | | // å¨ç½å·ä¸æé项ï¼å°å¡çæ ·å¼ |
| | | .tank-option { |
| | | padding: 8px 10px; |
| | | |
| | | .tank-option-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .tank-option-line { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | |
| | | // 客æ·åç§°ä¸æé项ï¼å°å¡çæ ·å¼ |
| | | .customer-option { |
| | | padding: 8px 10px; |
| | | |
| | | .customer-option-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .customer-option-line { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss"> |
| | | // 䏿颿¿æ¸²æå¨ body ä¸ï¼éå
¨å±æ ·å¼ |
| | | .oil-depot-select-popper { |
| | | .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: normal; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .oil-depot-option { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | background-color: #fafbfc; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background-color: #f0f7ff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // å¨ç½å·ä¸æé¢æ¿ï¼body ä¸ï¼éå
¨å±æ ·å¼ï¼ |
| | | .tank-select-popper { |
| | | .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: normal; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .tank-option { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | background-color: #fafbfc; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background-color: #f0f7ff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 客æ·åç§°ä¸æé¢æ¿ï¼body ä¸ï¼éå
¨å±æ ·å¼ï¼ |
| | | .customer-select-popper { |
| | | .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: normal; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .customer-option { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | background-color: #fafbfc; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background-color: #f0f7ff; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog v-model="isShow" |
| | | title="æ°å¢æ²¹ååºåº" |
| | | width="60%" |
| | | @close="closeModal"> |
| | | <el-form label-width="140px" |
| | | :model="formState" |
| | | label-position="top" |
| | | ref="formRef"> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="产ååç§°" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©äº§å', |
| | | trigger: 'change', |
| | | } |
| | | ]"> |
| | | <el-button type="primary" |
| | | @click="showProductSelectDialog = true"> |
| | | {{ formState.productName ? formState.productName : 'éæ©äº§å' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§æ ¼" |
| | | prop="model"> |
| | | <el-input v-model="formState.model" |
| | | disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åä½" |
| | | prop="unit"> |
| | | <el-input v-model="formState.unit" |
| | | disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">åºåºä¿¡æ¯</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåºç±»å«" |
| | | prop="outCategory" |
| | | :rules="[{ required: true, message: 'è¯·éæ©åºåºç±»å«', trigger: 'change' }]"> |
| | | <el-select v-model="formState.outCategory" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="客å" |
| | | value="客å" /> |
| | | <el-option label="代å¨" |
| | | value="代å¨" /> |
| | | <el-option label="éå®" |
| | | value="éå®" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¨åºåç§°" |
| | | prop="oilDepotId" |
| | | :rules="[{ required: true, message: 'è¯·éæ©å¨åºåç§°', trigger: 'change' }]"> |
| | | <el-select v-model="formState.oilDepotId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | popper-class="oil-depot-select-popper" |
| | | style="width: 100%" |
| | | @change="depotChange"> |
| | | <el-option v-for="item in oilDepotList" |
| | | :key="item.id" |
| | | :label="`${item.depotName}-${item.company || ''}`" |
| | | :value="item.id"> |
| | | <div class="oil-depot-option"> |
| | | <div class="oil-depot-option-title">{{ item.depotName }}-{{ item.company }}</div> |
| | | <div class="oil-depot-option-line">è´è´£äººï¼{{ item.chargePerson }}</div> |
| | | <div class="oil-depot-option-line">èç³»çµè¯ï¼{{ item.phone }}</div> |
| | | <div class="oil-depot-option-line">å¯ç¨æ¥æï¼{{ item.enableDate }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å¨ç½å·" |
| | | prop="tankId" |
| | | :rules="[{ required: true, message: 'è¯·éæ©å¨ç½å·', trigger: 'change' }]"> |
| | | <el-select v-model="formState.tankId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | popper-class="tank-select-popper" |
| | | style="width: 100%" |
| | | @change="tankChange"> |
| | | <el-option v-for="item in tankList" |
| | | :key="item.id" |
| | | :label="item.tankNo" |
| | | :value="item.id"> |
| | | <div class="tank-option"> |
| | | <div class="tank-option-title">{{ item.tankNo }}</div> |
| | | <div class="tank-option-line">大类ï¼{{ item.category }}</div> |
| | | <div class="tank-option-line">æ²¹åï¼{{ item.oilProduct }}</div> |
| | | <div class="tank-option-line">ç½å®¹ï¼{{ item.capacity }}</div> |
| | | <div class="tank-option-line">åºåä½é(m³)ï¼{{ item.remaining }}</div> |
| | | <div class="tank-option-line">ç§å®¢ä¿¡æ¯ï¼{{ item.tenantInfo || '--' }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåºæ¥æ" |
| | | prop="outDate" |
| | | :rules="[{ required: true, message: 'è¯·éæ©åºåºæ¥æ', trigger: 'change' }]"> |
| | | <el-date-picker v-model="formState.outDate" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | placeholder="è¯·éæ©" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ²¹å" |
| | | prop="oilProduct" |
| | | :rules="isOilProduct ? [ |
| | | { |
| | | required: true, |
| | | message: 'è¯·éæ©æ²¹å', |
| | | trigger: 'change', |
| | | } |
| | | ] : []"> |
| | | <el-input v-if="isOilProduct" |
| | | :model-value="formState.oilProduct" |
| | | readonly |
| | | placeholder="--" /> |
| | | <el-select v-else |
| | | v-model="formState.oilProduct" |
| | | placeholder="è¯·éæ©" |
| | | disabled |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåºå¨ä½(å¨)"> |
| | | <el-input :model-value="outTonnage === null ? '--' : outTonnage" |
| | | readonly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="客æ·åç§°" |
| | | prop="customerId" |
| | | :rules="[{ required: true, message: 'è¯·éæ©å®¢æ·åç§°', trigger: 'change' }]"> |
| | | <el-select v-model="formState.customerId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | filterable |
| | | popper-class="customer-select-popper" |
| | | style="width: 100%" |
| | | @change="customerChange"> |
| | | <el-option v-for="item in customerList" |
| | | :key="item.id" |
| | | :label="item.customerName" |
| | | :value="item.id"> |
| | | <div class="customer-option"> |
| | | <div class="customer-option-title">{{ item.customerName }}</div> |
| | | <div class="customer-option-line">é¶è¡åºæ¬æ·ï¼{{ item.basicBankAccount }}</div> |
| | | <div class="customer-option-line">é¶è¡è´¦å·ï¼{{ item.bankAccount }}</div> |
| | | <div class="customer-option-line">å°ååèç³»æ¹å¼ï¼{{ item.addressPhone }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="客æ·å¯¹æ¥äºº" |
| | | prop="contactPerson" |
| | | :rules="[{ required: true, message: '请è¾å
¥å®¢æ·å¯¹æ¥äºº', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.contactPerson" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="对æ¥äººçµè¯" |
| | | prop="contactPhone" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥å¯¹æ¥äººçµè¯', trigger: 'blur' }, |
| | | { pattern: /^1[3-9]\d{9}$/, message: '请è¾å
¥ææç11使æºå·ç ', trigger: 'blur' } |
| | | ]"> |
| | | <el-input v-model="formState.contactPhone" |
| | | placeholder="请è¾å
¥11使°å" |
| | | maxlength="11" |
| | | @input="phoneInput('contactPhone')" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">è£
æ²¹æä½ä¿¡æ¯</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="车ä½/é
å°æ£éªæ¯å¦æ£å¸¸" |
| | | prop="loadingInspectionStatus" |
| | | :rules="[{ required: true, message: 'è¯·éæ©è½¦ä½/é
å°æ£éªæ¯å¦æ£å¸¸', trigger: 'change' }]"> |
| | | <el-radio-group v-model="formState.loadingInspectionStatus"> |
| | | <el-radio value="æ£å¸¸">æ£å¸¸</el-radio> |
| | | <el-radio value="å¼å¸¸">å¼å¸¸</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="è£
车鹤ä½" |
| | | prop="loadingCranePosition" |
| | | :rules="[{ required: true, message: 'è¯·éæ©è£
车鹤ä½', trigger: 'change' }]"> |
| | | <el-select v-model="formState.loadingCranePosition" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="1#æ¬è£
" |
| | | value="1#æ¬è£
" /> |
| | | <el-option label="2#æ¬è£
" |
| | | value="2#æ¬è£
" /> |
| | | <el-option label="ä¸´æ¶æ³µ" |
| | | value="ä¸´æ¶æ³µ" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å¯åº¦" |
| | | prop="density" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥å¯åº¦', trigger: 'blur' }, |
| | | { pattern: /^\d+(\.\d{1,2})?$/, message: '请è¾å
¥æ°åï¼æå¤ä¿ç两ä½å°æ°', trigger: 'blur' }, |
| | | ]"> |
| | | <el-input v-model="formState.density" |
| | | placeholder="请è¾å
¥æ°åï¼æå¤ä¿ç两ä½å°æ°" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è£
æ²¹å
³é®ç¯èä¸è½¦è¾å
³é®ä½ç½®æç
§" |
| | | prop="loadingPhotos" |
| | | :rules="[{ required: true, message: '请ä¸ä¼ è£
æ²¹å
³é®ç¯èä¸è½¦è¾å
³é®ä½ç½®æç
§', trigger: 'change' }]"> |
| | | <ImageUpload v-model:file-list="formState.loadingPhotos" |
| | | :limit="10" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">è¿ç£
æ°æ®</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯é(å¨)" |
| | | prop="grossWeight" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥æ¯é', trigger: 'blur' }, |
| | | { pattern: /^\d+$/, message: 'åªè½è¾å
¥æ´æ°æ°å', trigger: 'blur' }, |
| | | ]"> |
| | | <el-input v-model="formState.grossWeight" |
| | | placeholder="请è¾å
¥æ´æ°æ°å" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç®é(å¨)" |
| | | prop="tareWeight" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥ç®é', trigger: 'blur' }, |
| | | { pattern: /^\d+$/, message: 'åªè½è¾å
¥æ´æ°æ°å', trigger: 'blur' }, |
| | | ]"> |
| | | <el-input v-model="formState.tareWeight" |
| | | placeholder="请è¾å
¥æ´æ°æ°å" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="åé(å¨)"> |
| | | <el-input :model-value="netWeight === null ? '--' : netWeight" |
| | | readonly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="äºé(å¨)"> |
| | | <el-input :model-value="lossQuantity === null ? '--' : lossQuantity" |
| | | readonly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å®é
å
¥åºä½ç§¯(å)"> |
| | | <el-input :model-value="actualVolume" |
| | | readonly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç£
åä¸ä¼ " |
| | | prop="poundPhotos" |
| | | :rules="[{ required: true, message: '请ä¸ä¼ ç£
å', trigger: 'change' }]"> |
| | | <ImageUpload v-model:file-list="formState.poundPhotos" |
| | | :limit="10" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">ç©æµä¿¡æ¯</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="叿ºå§å" |
| | | prop="driverName" |
| | | :rules="[{ required: true, message: '请è¾å
¥å¸æºå§å', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.driverName" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="叿ºçµè¯" |
| | | prop="driverPhone" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥å¸æºçµè¯', trigger: 'blur' }, |
| | | { pattern: /^1[3-9]\d{9}$/, message: '请è¾å
¥ææç11使æºå·ç ', trigger: 'blur' } |
| | | ]"> |
| | | <el-input v-model="formState.driverPhone" |
| | | placeholder="请è¾å
¥11使°å" |
| | | maxlength="11" |
| | | @input="phoneInput('driverPhone')" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¼è¿åå§å" |
| | | prop="escortName" |
| | | :rules="[{ required: true, message: '请è¾å
¥æ¼è¿åå§å', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.escortName" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¼è¿åçµè¯" |
| | | prop="escortPhone" |
| | | :rules="[ |
| | | { required: true, message: '请è¾å
¥æ¼è¿åçµè¯', trigger: 'blur' }, |
| | | { pattern: /^1[3-9]\d{9}$/, message: '请è¾å
¥ææç11使æºå·ç ', trigger: 'blur' } |
| | | ]"> |
| | | <el-input v-model="formState.escortPhone" |
| | | placeholder="请è¾å
¥11使°å" |
| | | maxlength="11" |
| | | @input="phoneInput('escortPhone')" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="车çå·" |
| | | prop="truckPlateNo" |
| | | :rules="[{ required: true, message: '请è¾å
¥è½¦çå·', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.truckPlateNo" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="车æçå·" |
| | | prop="trailerPlateNo" |
| | | :rules="[{ required: true, message: '请è¾å
¥è½¦æçå·', trigger: 'blur' }]"> |
| | | <el-input v-model="formState.trailerPlateNo" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" |
| | | @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeModal">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- 产åéæ©å¼¹çª --> |
| | | <ProductSelectDialog v-model="showProductSelectDialog" |
| | | @confirm="handleProductSelect" |
| | | single /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance, onMounted } from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import ImageUpload from "@/components/AttachmentUpload/image/index.vue"; |
| | | import { addOilOutRecordOnly } from "@/api/inventoryManagement/stockInventory.js"; |
| | | import { allOilDepot } from "@/api/basicData/oilDepot.js"; |
| | | import { allTankInfo } from "@/api/basicData/tankInfo.js"; |
| | | import { listCustomer } from "@/api/basicData/customer.js"; |
| | | import { productTreeList } from "@/api/basicData/product.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits(["update:visible", "completed"]); |
| | | |
| | | const buildEmptyForm = () => ({ |
| | | productId: undefined, |
| | | productModelId: undefined, |
| | | productName: "", |
| | | model: "", |
| | | unit: "", |
| | | outCategory: undefined, |
| | | oilDepotId: undefined, |
| | | oilDepotName: "", |
| | | tankId: undefined, |
| | | tankNo: "", |
| | | outDate: "", |
| | | oilProduct: undefined, |
| | | customerId: undefined, |
| | | customerName: "", |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | loadingInspectionStatus: undefined, |
| | | loadingCranePosition: undefined, |
| | | loadingPhotos: [], |
| | | density: undefined, |
| | | grossWeight: undefined, |
| | | tareWeight: undefined, |
| | | poundPhotos: [], |
| | | driverName: "", |
| | | driverPhone: "", |
| | | escortName: "", |
| | | escortPhone: "", |
| | | truckPlateNo: "", |
| | | trailerPlateNo: "", |
| | | }); |
| | | |
| | | const formState = ref(buildEmptyForm()); |
| | | |
| | | const oilDepotList = ref([]); |
| | | const tankList = ref([]); |
| | | const customerList = ref([]); |
| | | const oilProductOptions = ref([]); |
| | | const showProductSelectDialog = ref(false); |
| | | |
| | | // å¨äº§åæ 䏿¥æ¾"æ²¹å"åç±»èç¹ |
| | | const findOilNode = nodes => { |
| | | for (const node of nodes || []) { |
| | | if (node.productName === "æ²¹å") { |
| | | return node; |
| | | } |
| | | if (node.children && node.children.length) { |
| | | const found = findOilNode(node.children); |
| | | if (found) { |
| | | return found; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | // æéåååç§°å½ä¸çæ²¹åéé¡¹ï¼æ²¹åèç¹åé¡¹ï¼æ¥èªäº§åç»´æ¤æ¨¡åï¼ |
| | | const matchedOilOption = computed(() => |
| | | oilProductOptions.value.find( |
| | | item => item.productName === formState.value.productName |
| | | ) |
| | | ); |
| | | |
| | | // åªæé䏿²¹ååæ®µé项éæçå
·ä½æ²¹åæå¯ç¨æ²¹ååæ®µï¼"æ²¹å"大类æ¬èº«ä¸å¯ç¨ |
| | | const isOilProduct = computed(() => !!matchedOilOption.value); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit("update:visible", val); |
| | | }, |
| | | }); |
| | | |
| | | // åé(å¨) = æ¯é - ç®é |
| | | const netWeight = computed(() => { |
| | | const g = formState.value.grossWeight; |
| | | const t = formState.value.tareWeight; |
| | | if ([g, t].some(v => v === null || v === undefined || v === "")) { |
| | | return null; |
| | | } |
| | | return Number(g) - Number(t); |
| | | }); |
| | | |
| | | // äºé(å¨) = åéçè´æ° |
| | | const lossQuantity = computed(() => { |
| | | if (netWeight.value === null) { |
| | | return null; |
| | | } |
| | | return -netWeight.value; |
| | | }); |
| | | |
| | | // å®é
å
¥åºä½ç§¯(å) = å®é
åé(kg) ÷ å¯åº¦(kg/L)ï¼åéå¨ Ã 1000 转 kg |
| | | const actualVolume = computed(() => { |
| | | const d = formState.value.density; |
| | | if (netWeight.value === null || d === null || d === undefined || d === "" || Number(d) <= 0) { |
| | | return 0; |
| | | } |
| | | return Math.round(((netWeight.value * 1000) / Number(d)) * 100) / 100; |
| | | }); |
| | | |
| | | // åºåºå¨ä½(å¨) = åéï¼éæ±æªç»å
¬å¼ï¼ææåé带åºï¼ |
| | | const outTonnage = computed(() => netWeight.value); |
| | | |
| | | let { proxy } = getCurrentInstance(); |
| | | |
| | | const closeModal = () => { |
| | | proxy.resetForm("formRef"); |
| | | formState.value = buildEmptyForm(); |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | // çµè¯è¾å
¥éå¶ï¼åªå
许æ°åï¼æå¤11ä½ |
| | | const phoneInput = field => { |
| | | formState.value[field] = String(formState.value[field] ?? "") |
| | | .replace(/\D/g, "") |
| | | .slice(0, 11); |
| | | }; |
| | | |
| | | // 产åéæ©å¤ç |
| | | 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.model = product.model; |
| | | formState.value.productModelId = product.id; |
| | | formState.value.unit = product.unit; |
| | | // æ²¹åé项ä¸åååç§°åæ¥ï¼å½ä¸æ²¹åé项åèªå¨å¸¦åºè¯¥æ²¹åï¼æªå½ä¸åæ¸
空并ç¦ç¨ |
| | | formState.value.oilProduct = matchedOilOption.value |
| | | ? product.productName |
| | | : undefined; |
| | | showProductSelectDialog.value = false; |
| | | proxy.$refs["formRef"]?.validateField("productModelId"); |
| | | } |
| | | }; |
| | | |
| | | // å¨åºéæ©æ¹åï¼è®°å½åºå-å
¬å¸å |
| | | const depotChange = id => { |
| | | const depot = oilDepotList.value.find(item => item.id === id); |
| | | formState.value.oilDepotName = depot |
| | | ? `${depot.depotName}-${depot.company || ""}` |
| | | : ""; |
| | | }; |
| | | |
| | | // å¨ç½éæ©æ¹åï¼è®°å½å¨ç½å· |
| | | const tankChange = id => { |
| | | const tank = tankList.value.find(item => item.id === id); |
| | | formState.value.tankNo = tank?.tankNo || ""; |
| | | }; |
| | | |
| | | // 客æ·éæ©æ¹åï¼ç»å®å®¢æ·æ¡£æ¡(ç§æµ·)ï¼èªå¨å¸¦åºå¯¹æ¥äººä¸å¯¹æ¥çµè¯ |
| | | const customerChange = id => { |
| | | const customer = customerList.value.find(item => item.id === id); |
| | | if (customer) { |
| | | formState.value.customerName = customer.customerName || ""; |
| | | formState.value.contactPerson = customer.contactPerson || ""; |
| | | formState.value.contactPhone = customer.contactPhone || ""; |
| | | } else { |
| | | formState.value.customerName = ""; |
| | | formState.value.contactPerson = ""; |
| | | formState.value.contactPhone = ""; |
| | | } |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | if (!formState.value.productModelId) { |
| | | proxy.$modal.msgError("è¯·éæ©äº§å"); |
| | | return; |
| | | } |
| | | // 计ç®ç»æé表åæäº¤ |
| | | formState.value.outTonnage = outTonnage.value; |
| | | formState.value.netWeight = netWeight.value; |
| | | formState.value.lossQuantity = lossQuantity.value; |
| | | formState.value.actualVolume = actualVolume.value; |
| | | // ç
§ç转 JSON å符串æäº¤ï¼åç«¯åæ®µä¸ºææ¬åå¨ï¼ |
| | | formState.value.loadingPhotos = JSON.stringify(formState.value.loadingPhotos || []); |
| | | formState.value.poundPhotos = JSON.stringify(formState.value.poundPhotos || []); |
| | | |
| | | addOilOutRecordOnly(formState.value).then(res => { |
| | | proxy.$modal.msgSuccess("æäº¤æå"); |
| | | closeModal(); |
| | | emit("completed"); |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | allOilDepot().then(res => { |
| | | oilDepotList.value = res?.data || []; |
| | | }); |
| | | productTreeList().then(res => { |
| | | const oilNode = findOilNode(res); |
| | | oilProductOptions.value = oilNode?.children || []; |
| | | }); |
| | | allTankInfo().then(res => { |
| | | tankList.value = res?.data || []; |
| | | }); |
| | | listCustomer({ current: 1, size: 1000, type: 0 }).then(res => { |
| | | customerList.value = res?.data?.records || []; |
| | | }); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | // 表ååæ æ é¢ï¼èè²ç«æ¡ + æµ
èåºè²ï¼çªåºååº |
| | | .form-section-title { |
| | | margin: 18px 0 14px; |
| | | padding: 8px 14px; |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | color: #1d6fd8; |
| | | background: linear-gradient(90deg, rgba(64, 158, 255, 0.14), rgba(64, 158, 255, 0.02)); |
| | | border-left: 4px solid #409eff; |
| | | border-radius: 3px; |
| | | } |
| | | |
| | | // å¨åºåç§°ä¸æé项ï¼å°å¡çæ ·å¼ |
| | | .oil-depot-option { |
| | | padding: 8px 10px; |
| | | |
| | | .oil-depot-option-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .oil-depot-option-line { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | |
| | | // å¨ç½å·ä¸æé项ï¼å°å¡çæ ·å¼ |
| | | .tank-option { |
| | | padding: 8px 10px; |
| | | |
| | | .tank-option-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .tank-option-line { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | |
| | | // 客æ·åç§°ä¸æé项ï¼å°å¡çæ ·å¼ |
| | | .customer-option { |
| | | padding: 8px 10px; |
| | | |
| | | .customer-option-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .customer-option-line { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss"> |
| | | // 䏿颿¿æ¸²æå¨ body ä¸ï¼éå
¨å±æ ·å¼ |
| | | .oil-depot-select-popper { |
| | | .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: normal; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .oil-depot-option { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | background-color: #fafbfc; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background-color: #f0f7ff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // å¨ç½å·ä¸æé¢æ¿ï¼body ä¸ï¼éå
¨å±æ ·å¼ï¼ |
| | | .tank-select-popper { |
| | | .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: normal; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .tank-option { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | background-color: #fafbfc; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background-color: #f0f7ff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 客æ·åç§°ä¸æé¢æ¿ï¼body ä¸ï¼éå
¨å±æ ·å¼ï¼ |
| | | .customer-select-popper { |
| | | .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: normal; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .customer-option { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | background-color: #fafbfc; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background-color: #f0f7ff; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <div style="display: flex; gap: 10px; flex-wrap: nowrap;"> |
| | | <el-button type="primary" |
| | | @click="isShowNewModal = true">æ°å¢åºå</el-button> |
| | | <el-button type="primary" |
| | | @click="isShowOilInModal = true">æ°å¢æ²¹åå
¥åº</el-button> |
| | | <el-button type="primary" |
| | | @click="isShowOilOutModal = true">æ°å¢æ²¹ååºåº</el-button> |
| | | <el-button type="info" |
| | | plain |
| | | icon="Upload" |
| | |
| | | width="60" /> |
| | | <el-table-column label="产ååç§°" |
| | | prop="productName" |
| | | min-width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="è§æ ¼åå·" |
| | | prop="model" |
| | | min-width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="åä½" |
| | | prop="unit" |
| | | min-width="70" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="æ¹å·" |
| | | prop="batchNo" |
| | | min-width="150" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="åæ ¼åºåæ°é" |
| | | prop="qualifiedQuantity" |
| | | min-width="110" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="ä¸åæ ¼åºåæ°é" |
| | | prop="unQualifiedQuantity" |
| | | min-width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="åæ ¼å»ç»æ°é" |
| | | prop="qualifiedLockedQuantity" |
| | | min-width="110" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="ä¸åæ ¼å»ç»æ°é" |
| | | prop="unQualifiedLockedQuantity" |
| | | min-width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="åºåé¢è¦æ°é" |
| | | prop="warnNum" |
| | | min-width="110" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="夿³¨" |
| | | prop="remark" |
| | | min-width="150" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="æè¿æ´æ°æ¶é´" |
| | | prop="updateTime" |
| | | min-width="160" |
| | | show-overflow-tooltip /> |
| | | <el-table-column fixed="right" |
| | | label="æä½" |
| | |
| | | <new-stock-inventory v-if="isShowNewModal" |
| | | v-model:visible="isShowNewModal" |
| | | :top-product-parent-id="props.productId" |
| | | @completed="handleQuery" /> |
| | | <oil-stock-in-dialog v-if="isShowOilInModal" |
| | | v-model:visible="isShowOilInModal" |
| | | @completed="handleQuery" /> |
| | | <oil-stock-out-dialog v-if="isShowOilOutModal" |
| | | v-model:visible="isShowOilOutModal" |
| | | @completed="handleQuery" /> |
| | | <subtract-stock-inventory v-if="isShowSubtractModal" |
| | | v-model:visible="isShowSubtractModal" |
| | |
| | | const NewStockInventory = defineAsyncComponent(() => |
| | | import("@/views/inventoryManagement/stockManagement/New.vue") |
| | | ); |
| | | const OilStockInDialog = defineAsyncComponent(() => |
| | | import("@/views/inventoryManagement/stockManagement/OilStockInDialog.vue") |
| | | ); |
| | | const OilStockOutDialog = defineAsyncComponent(() => |
| | | import("@/views/inventoryManagement/stockManagement/OilStockOutDialog.vue") |
| | | ); |
| | | const SubtractStockInventory = defineAsyncComponent(() => |
| | | import("@/views/inventoryManagement/stockManagement/Subtract.vue") |
| | | ); |
| | |
| | | const total = ref(0); |
| | | // æ¯å¦æ¾ç¤ºæ°å¢å¼¹æ¡ |
| | | const isShowNewModal = ref(false); |
| | | // æ¯å¦æ¾ç¤ºæ²¹åå
¥åºå¼¹æ¡ |
| | | const isShowOilInModal = ref(false); |
| | | // æ¯å¦æ¾ç¤ºæ²¹ååºåºå¼¹æ¡ |
| | | const isShowOilOutModal = ref(false); |
| | | // æ¯å¦æ¾ç¤ºé¢ç¨å¼¹æ¡ |
| | | const isShowSubtractModal = ref(false); |
| | | // æ¯å¦æ¾ç¤ºå»ç»/è§£å»å¼¹æ¡ |
| | |
| | | prop="projectName" |
| | | width="320" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="éè´ç±»å«" |
| | | prop="purchaseCategory" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="æè´§æ¹å¼" |
| | | prop="pickupMethod" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="éè´æ²¹å" |
| | | prop="purchaseOilProduct" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="ç©æµæ¹å¼" |
| | | prop="logisticsMethod" |
| | | width="100" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="éè´æ²¹åº" |
| | | prop="oilDepotName" |
| | | width="150" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="客æ·åç§°" |
| | | prop="customerName" |
| | | width="150" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="æä½³å°ç«æ¥æ" |
| | | prop="bestArrivalDate" |
| | | width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="éè´æ°éï¼å¨ï¼" |
| | | prop="purchaseQuantity" |
| | | width="120" |
| | | align="center" /> |
| | | <el-table-column label="éè´ç³è¯·è®¢åç¶æ" |
| | | prop="purchaseOrderStatus" |
| | | width="140" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="审æ¹ç¶æ" |
| | | prop="approvalStatus" |
| | | width="100" |
| | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="仿¬¾æ¹å¼"> |
| | | <el-input v-model="form.paymentMethod" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¾è®¢æ¥æï¼" |
| | | prop="executionDate"> |
| | | <el-form-item label="æä½³å°ç«æ¥æï¼" |
| | | prop="bestArrivalDate"> |
| | | <el-date-picker style="width: 100%" |
| | | v-model="form.executionDate" |
| | | v-model="form.bestArrivalDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="仿¬¾æ¹å¼"> |
| | | <el-input v-model="form.paymentMethod" |
| | | placeholder="请è¾å
¥" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å½å
¥äººï¼" |
| | | prop="recorderId"> |
| | | <el-select v-model="form.recorderId" |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ç¾è®¢æ¥æï¼" |
| | | prop="executionDate"> |
| | | <el-date-picker style="width: 100%" |
| | | v-model="form.executionDate" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="å½å
¥æ¥æï¼" |
| | | prop="entryDate"> |
| | | <el-date-picker style="width: 100%" |
| | |
| | | type="date" |
| | | placeholder="è¯·éæ©" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">éè´å
¥åºæäº¤</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç³è¯·æäº¤æ¶é´ï¼" |
| | | prop="applicationSubmitTime"> |
| | | <el-date-picker style="width: 100%" |
| | | v-model="form.applicationSubmitTime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | placeholder="è¯·éæ©" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´ç±»å«ï¼" |
| | | prop="purchaseCategory"> |
| | | <el-radio-group v-model="form.purchaseCategory" |
| | | @change="purchaseCategoryChange"> |
| | | <el-radio value="客å">客å</el-radio> |
| | | <el-radio value="代å¨">代å¨</el-radio> |
| | | <el-radio value="éè´å
¥åº">éè´å
¥åº</el-radio> |
| | | <el-radio value="éè´ç´é">éè´ç´é</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´æ²¹åï¼" |
| | | prop="purchaseOilProduct"> |
| | | <el-select v-model="form.purchaseOilProduct" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="æ±½#92" |
| | | value="æ±½#92" /> |
| | | <el-option label="æ±½#95" |
| | | value="æ±½#95" /> |
| | | <el-option label="æ´#0" |
| | | value="æ´#0" /> |
| | | <el-option label="æ´#-35" |
| | | value="æ´#-35" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç©æµæ¹å¼ï¼" |
| | | prop="logisticsMethod"> |
| | | <el-select v-model="form.logisticsMethod" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="åå®¶é
é" |
| | | value="åå®¶é
é" /> |
| | | <el-option label="å§å¤ç©æµ" |
| | | value="å§å¤ç©æµ" /> |
| | | <el-option label="客æ·èªæ" |
| | | value="客æ·èªæ" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æè´§æ¹å¼ï¼" |
| | | prop="pickupMethod"> |
| | | <el-radio-group v-model="form.pickupMethod"> |
| | | <el-radio value="æä¸æè´§">æä¸æè´§</el-radio> |
| | | <el-radio value="æè´§">æè´§</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´æ²¹åºï¼" |
| | | prop="oilDepotId"> |
| | | <el-select v-model="form.oilDepotId" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | popper-class="oil-depot-select-popper" |
| | | style="width: 100%"> |
| | | <el-option v-for="item in oilDepotList" |
| | | :key="item.id" |
| | | :label="item.depotName" |
| | | :value="item.id"> |
| | | <div class="oil-depot-option"> |
| | | <div class="oil-depot-option-title">{{ item.depotName }}</div> |
| | | <div class="oil-depot-option-line">è´è´£äººï¼{{ item.chargePerson }}</div> |
| | | <div class="oil-depot-option-line">èç³»çµè¯ï¼{{ item.phone }}</div> |
| | | <div class="oil-depot-option-line">æå±å
¬å¸ï¼{{ item.company }}</div> |
| | | <div class="oil-depot-option-line">å¯ç¨æ¥æï¼{{ item.enableDate }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </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="!['代å¨', 'éè´ç´é'].includes(form.purchaseCategory)" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´æ°éï¼å¨ï¼ï¼" |
| | | prop="purchaseQuantity"> |
| | | <el-input-number v-model="form.purchaseQuantity" |
| | | :precision="0" |
| | | :step="1" |
| | | :min="0" |
| | | placeholder="请è¾å
¥" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="form-section-title">ç³»ç»ä¿¡æ¯</div> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´ç³è¯·è®¢åç¶æï¼" |
| | | prop="purchaseOrderStatus"> |
| | | <el-select v-model="form.purchaseOrderStatus" |
| | | placeholder="è¯·éæ©" |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option label="å·²ç³è¯·ï¼æªè£
车" |
| | | value="å·²ç³è¯·ï¼æªè£
车" /> |
| | | <el-option label="以åºåï¼æªå
¥åº" |
| | | value="以åºåï¼æªå
¥åº" /> |
| | | <el-option label="å·²å
¥åº" |
| | | value="å·²å
¥åº" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | delPurchaseTemplate, |
| | | batchGeneratePurchaseInboundSteps, |
| | | } from "@/api/procurementManagement/procurementLedger.js"; |
| | | import { allOilDepot } from "@/api/basicData/oilDepot.js"; |
| | | import useFormData from "@/hooks/useFormData.js"; |
| | | const FileList = defineAsyncComponent(() => |
| | | import("@/components/Dialog/FileList.vue") |
| | |
| | | const productOptions = ref([]); |
| | | const salesContractList = ref([]); |
| | | const supplierList = ref([]); |
| | | const oilDepotList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const recordId = ref(); |
| | | const fileListDialogVisible = ref(false); |
| | |
| | | paymentMethod: "", |
| | | executionDate: "", |
| | | isChecked: false, |
| | | purchaseCategory: "", |
| | | purchaseOilProduct: "", |
| | | logisticsMethod: "", |
| | | pickupMethod: "", |
| | | oilDepotId: "", |
| | | customerName: "", |
| | | bestArrivalDate: "", |
| | | purchaseQuantity: "", |
| | | purchaseOrderStatus: "", |
| | | applicationSubmitTime: "", |
| | | }, |
| | | rules: { |
| | | purchaseContractNumber: [ |
| | |
| | | supplierId: [{ required: true, message: "请è¾å
¥", trigger: "blur" }], |
| | | entryDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | executionDate: [{ required: true, message: "è¯·éæ©", trigger: "change" }], |
| | | purchaseCategory: [ |
| | | { required: true, message: "è¯·éæ©éè´ç±»å«", trigger: "change" }, |
| | | ], |
| | | purchaseOilProduct: [ |
| | | { required: true, message: "è¯·éæ©éè´æ²¹å", trigger: "change" }, |
| | | ], |
| | | oilDepotId: [ |
| | | { required: true, message: "è¯·éæ©éè´æ²¹åº", trigger: "change" }, |
| | | ], |
| | | purchaseQuantity: [ |
| | | { required: true, message: "请è¾å
¥éè´æ°é", trigger: "change" }, |
| | | ], |
| | | }, |
| | | }); |
| | | const { form, rules } = toRefs(data); |
| | |
| | | isTemplateNameDuplicate.value = false; |
| | | try { |
| | | // å¹¶è¡å è½½åºç¡æ°æ® |
| | | const [salesRes, supplierRes] = await Promise.all([ |
| | | const [salesRes, supplierRes, oilDepotRes] = await Promise.all([ |
| | | getSalesNo(), |
| | | getOptions(), |
| | | allOilDepot(), |
| | | ]); |
| | | |
| | | salesContractList.value = salesRes || []; |
| | |
| | | supplierList.value = (supplierRes.data || []).filter( |
| | | item => item.isWhite === 0 |
| | | ); |
| | | oilDepotList.value = oilDepotRes?.data || []; |
| | | |
| | | form.value.entryDate = getCurrentDate(); |
| | | |
| | |
| | | } |
| | | } |
| | | }; |
| | | // éè´ç±»å«æ¹åï¼ä»
代å¨/éè´ç´éæ¶å®¢æ·åç§°å¯ç¨ï¼åæ¢åæ¸
空 |
| | | const purchaseCategoryChange = val => { |
| | | if (!["代å¨", "éè´ç´é"].includes(val)) { |
| | | form.value.customerName = ""; |
| | | } |
| | | }; |
| | | |
| | | // éå®ååéæ©æ¹åæ¹æ³ |
| | | const salesLedgerChange = async row => { |
| | | console.log("row", row); |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | // 表ååæ æ é¢ï¼èè²ç«æ¡ + æµ
èåºè²ï¼çªåºååº |
| | | .form-section-title { |
| | | margin: 18px 0 14px; |
| | | padding: 8px 14px; |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | color: #1d6fd8; |
| | | background: linear-gradient(90deg, rgba(64, 158, 255, 0.14), rgba(64, 158, 255, 0.02)); |
| | | border-left: 4px solid #409eff; |
| | | border-radius: 3px; |
| | | } |
| | | |
| | | .invalid-row { |
| | | opacity: 0.6; |
| | | background-color: #f5f7fa; |
| | |
| | | .select-button-group { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | // éè´æ²¹åºä¸æé项ï¼å°å¡çæ ·å¼ |
| | | .oil-depot-option { |
| | | padding: 8px 10px; |
| | | |
| | | .oil-depot-option-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .oil-depot-option-line { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | |
| | | // 审æ¹äººèç¹å®¹å¨æ ·å¼ |
| | |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss"> |
| | | // 䏿颿¿æ¸²æå¨ body ä¸ï¼éå
¨å±æ ·å¼ |
| | | .oil-depot-select-popper { |
| | | .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: normal; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .oil-depot-option { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | background-color: #fafbfc; |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | background-color: #f0f7ff; |
| | | } |
| | | } |
| | | } |
| | | </style> |