Browse Source
feat(order): 添加国际化支持并优化权限控制
feat(order): 添加国际化支持并优化权限控制
- 在多个组件中添加locale属性支持中英文切换 - 实现表格列标题的国际化显示 - 为首页代办功能添加菜单权限控制 - 移除菜单管理中不必要的"菜单"文字重复显示 - 禁止菜单路由字段在编辑时被修改 - 限制菜单删除功能仅对非一级菜单生效 - 新增英文版PO订单查询页面支持国际化显示master
8 changed files with 1107 additions and 28 deletions
-
12src/views/common/home.vue
-
37src/views/modules/order/com_inspectionDetailList.vue
-
19src/views/modules/order/com_logisticsPoList.vue
-
87src/views/modules/order/com_poOrderDetail.vue
-
14src/views/modules/order/com_poPartAttribute.vue
-
960src/views/modules/order/poOrder_search_en.vue
-
2src/views/modules/sys/menu-add-or-update.vue
-
4src/views/modules/sys/menu.vue
@ -0,0 +1,960 @@ |
|||
<template> |
|||
<div class="mod-config"> |
|||
<com-po-order-customer-picker |
|||
:site="searchData.site" |
|||
v-model="searchData.customer" |
|||
@change="onSessionCustomerChange" /> |
|||
<!-- Search Conditions --> |
|||
<el-form :inline="true" label-position="top" :model="searchData"> |
|||
<el-form-item label="PO No"> |
|||
<el-input v-model="searchData.poNo" clearable style="width: 140px" @keyup.enter.native="handleSearch"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="Order Type"> |
|||
<el-select v-model="searchData.orderType" placeholder="Please select" style="width: 120px" clearable> |
|||
<el-option |
|||
v-for="item in poOrderTypeSearchOptions" |
|||
:key="item.value" |
|||
:label="item.label" |
|||
:value="item.value" /> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<span style="cursor: pointer" slot="label" @click="openSearchBaseList(2017)"><a href="javascript:void(0)">Part No</a></span> |
|||
<el-input v-model="searchData.partNo" clearable style="width: 120px" @keyup.enter.native="handleSearch"></el-input> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<span style="cursor: pointer" slot="label" @click="openSearchBaseList(520)"><a href="javascript:void(0)">Supplier Code</a></span> |
|||
<el-input v-model="searchData.supplierNo" clearable style="width: 120px" @keyup.enter.native="handleSearch"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="SKU"> |
|||
<el-input v-model="searchData.sku" clearable style="width: 120px" @keyup.enter.native="handleSearch"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="Status"> |
|||
<el-select v-model="searchData.status" placeholder="Please select" style="width:100px" clearable> |
|||
<el-option label="All" value=""></el-option> |
|||
<el-option |
|||
v-for="item in poOrderStatusOptions" |
|||
:key="item.value" |
|||
:label="item.label" |
|||
:value="item.value" /> |
|||
</el-select> |
|||
</el-form-item> |
|||
</el-form> |
|||
|
|||
<el-form :inline="true" label-position="top" style="margin-top:10px"> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="handleSearch" :disabled="!searchData.customer">Search</el-button> |
|||
<el-button type="primary" @click="exportExcel" style="margin-left: 2px">Export</el-button> |
|||
<el-button @click="resetSearch">Reset</el-button> |
|||
<el-button type="warning" plain @click="advancedQueryVisible = true" style="margin-left: 2px">Advanced Query</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
|
|||
<!-- Data Table --> |
|||
<el-table |
|||
ref="poTable" |
|||
:height="height" |
|||
:data="dataList" |
|||
border |
|||
highlight-current-row |
|||
v-loading="loading" |
|||
@row-click="changeData" |
|||
style="width: 100%;"> |
|||
<el-table-column |
|||
v-for="(item, index) in visibleColumns" |
|||
:key="item.serialNumber || index" |
|||
:sortable="item.columnSortable" |
|||
:prop="item.columnProp" |
|||
:header-align="item.headerAlign" |
|||
:show-overflow-tooltip="item.showOverflowTooltip" |
|||
:align="item.align" |
|||
:fixed="item.fixed === '' ? false : item.fixed" |
|||
:min-width="item.columnWidth" |
|||
:label="item.columnLabel"> |
|||
<template slot-scope="scope"> |
|||
<span>{{ formatColumnCell(scope.row, item) }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
|
|||
<!-- Pagination --> |
|||
<el-pagination |
|||
@size-change="sizeChangeHandle" |
|||
@current-change="currentChangeHandle" |
|||
:current-page="pageIndex" |
|||
:page-sizes="[20, 50, 100, 200, 500]" |
|||
:page-size="pageSize" |
|||
:total="totalPage" |
|||
layout="total, sizes, prev, pager, next, jumper"> |
|||
</el-pagination> |
|||
|
|||
<!-- Detail Tabs --> |
|||
<el-tabs v-model="activeTab" style="margin-top: 0px; width: 99%;" @tab-click="handleTabClick" class="customer-tab" type="border-card"> |
|||
<!-- Order Detail --> |
|||
<el-tab-pane label="Order Detail" name="orderDetail"> |
|||
<po-order-detail |
|||
:detail-data="currentRow" |
|||
:schema-fields="fieldSchemaFields" |
|||
locale="en" /> |
|||
</el-tab-pane> |
|||
<!-- Logistics --> |
|||
<el-tab-pane label="Logistics" name="logistics"> |
|||
<logistics-po-list ref="logisticsPoList" locale="en" /> |
|||
</el-tab-pane> |
|||
<!-- Inspection Detail --> |
|||
<el-tab-pane label="Inspection Detail" name="inspectionDetail"> |
|||
<inspection-detail-list ref="inspectionDetailList" locale="en" /> |
|||
</el-tab-pane> |
|||
<!-- Part Attribute (Read Only) --> |
|||
<el-tab-pane label="Part Attribute" name="partAttribute"> |
|||
<po-part-attribute ref="partAttributeTab" locale="en" /> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
|
|||
<po-order-advanced-query |
|||
:visible.sync="advancedQueryVisible" |
|||
:advanced-query-data="advancedQueryData" |
|||
@query="handleSearch" /> |
|||
|
|||
<ChooselistEam ref="eamList" @getBaseData="getEamData" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { searchPoDetailPage, searchPoDetailAdvancedPage, getPoFieldSchema } from '@/api/order/poOrder.js' |
|||
import { |
|||
createAdvancedQueryData, |
|||
createAdvancedQueryDataFromSchema, |
|||
buildPoOrderQueryParams |
|||
} from './poOrderAdvancedQueryHelper.js' |
|||
import { |
|||
applyFieldSchemaToColumns, |
|||
getAdvancedQueryFieldsFromSchema, |
|||
normalizeSchemaRowValues |
|||
} from './poOrderFieldSchemaHelper.js' |
|||
import excel from '@/utils/excel-util.js' |
|||
import LogisticsPoList from './com_logisticsPoList.vue' |
|||
import InspectionDetailList from './com_inspectionDetailList.vue' |
|||
import PoPartAttribute from './com_poPartAttribute.vue' |
|||
import PoOrderDetail from './com_poOrderDetail.vue' |
|||
import PoOrderAdvancedQuery from './com_poOrderAdvancedQuery.vue' |
|||
import ChooselistEam from '@/views/modules/common/Chooselist_eam.vue' |
|||
import ComPoOrderCustomerPicker from './com_poOrder_CustomerPicker.vue' |
|||
import { PO_ORDER_STATUS_OPTIONS } from './poOrderStatusOptions.js' |
|||
import { PO_ORDER_TYPE_OPTIONS, formatPoOrderTypeLabel } from './poOrderTypeOptions.js' |
|||
import { searchPartInfo } from '@/api/part/partInfo.js' |
|||
|
|||
export default { |
|||
components: { |
|||
LogisticsPoList, |
|||
InspectionDetailList, |
|||
PoPartAttribute, |
|||
PoOrderDetail, |
|||
PoOrderAdvancedQuery, |
|||
ChooselistEam, |
|||
ComPoOrderCustomerPicker |
|||
}, |
|||
name: 'PoOrderQueryEn', |
|||
data() { |
|||
return { |
|||
loading: false, |
|||
exportLoading: false, |
|||
height: 400, |
|||
activeTab: 'orderDetail', |
|||
pageIndex: 1, |
|||
pageSize: 20, |
|||
totalPage: 0, |
|||
dataList: [], |
|||
currentRow: {}, |
|||
advancedQueryVisible: false, |
|||
eamTagNo: '', |
|||
poOrderTypeSearchOptions: [{ label: 'All', value: '' }, ...PO_ORDER_TYPE_OPTIONS], |
|||
/** Advanced query object (read by search/export; only reset in dialog) */ |
|||
advancedQueryData: createAdvancedQueryData(), |
|||
fieldSchemaFields: [], |
|||
baseColumnList: null, |
|||
poOrderStatusOptions: PO_ORDER_STATUS_OPTIONS, |
|||
searchData: { |
|||
site: this.$store.state.user.site, |
|||
customer: '', |
|||
buyer: '', |
|||
poNo: '', |
|||
orderType: '', |
|||
partNo: '', |
|||
supplierNo: '', |
|||
sku: '', |
|||
status: '', |
|||
supplierName: '', |
|||
feeDateStart: '', |
|||
feeDateEnd: '' |
|||
}, |
|||
// Column config (consistent with original page, hides edit related columns) |
|||
columnList: [ |
|||
{ |
|||
columnProp: 'poNo', |
|||
columnLabel: 'PO No', |
|||
align: 'center', |
|||
columnWidth: 120, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'orderType', |
|||
columnLabel: 'Order Type', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'customer', |
|||
columnLabel: 'Customer', |
|||
align: 'center', |
|||
columnWidth: 180, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'buyer', |
|||
columnLabel: 'Buyer', |
|||
align: 'center', |
|||
columnWidth: 90, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'supplierName', |
|||
columnLabel: 'Vendor Name', |
|||
align: 'center', |
|||
columnWidth: 180, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'shortOffice', |
|||
columnLabel: 'V_Short_Office', |
|||
align: 'center', |
|||
columnWidth: 110, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'shortNpc', |
|||
columnLabel: 'V_Short_NPC', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'partNo', |
|||
columnLabel: 'Part No', |
|||
align: 'center', |
|||
columnWidth: 120, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'item', |
|||
columnLabel: 'Item', |
|||
align: 'center', |
|||
columnWidth: 120, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'categoryName', |
|||
columnLabel: 'Category', |
|||
align: 'center', |
|||
columnWidth: 90, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'sku', |
|||
columnLabel: 'SKU', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'price', |
|||
columnLabel: 'Unit Price', |
|||
align: 'center', |
|||
columnWidth: 90, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'qty', |
|||
columnLabel: 'PO Qty', |
|||
align: 'center', |
|||
columnWidth: 80, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'value', |
|||
columnLabel: 'PO Value', |
|||
align: 'center', |
|||
columnWidth: 90, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'shipQty', |
|||
columnLabel: 'A-Qty', |
|||
align: 'center', |
|||
columnWidth: 80, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'sumPrice', |
|||
columnLabel: 'A-Value', |
|||
align: 'center', |
|||
columnWidth: 90, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'departure', |
|||
columnLabel: 'Departure Port', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'destination', |
|||
columnLabel: 'Destination Port', |
|||
align: 'center', |
|||
columnWidth: 110, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'shipVia', |
|||
columnLabel: 'Method', |
|||
align: 'center', |
|||
columnWidth: 90, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'orderDate', |
|||
columnLabel: 'Buyer Release Date', |
|||
align: 'center', |
|||
columnWidth: 130, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'enquiry', |
|||
columnLabel: 'Planner Release Date', |
|||
align: 'center', |
|||
columnWidth: 140, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'status', |
|||
columnLabel: 'Status', |
|||
align: 'center', |
|||
columnWidth: 80, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'confirmed', |
|||
columnLabel: 'PI Confirmed Date', |
|||
align: 'center', |
|||
columnWidth: 120, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'wantReceiveDate', |
|||
columnLabel: 'Original Arrival Date', |
|||
align: 'center', |
|||
columnWidth: 130, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'narrival', |
|||
columnLabel: 'Final Confirmed Arrival Date', |
|||
align: 'center', |
|||
columnWidth: 110, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'crd', |
|||
columnLabel: 'PI Confirmed CRD', |
|||
align: 'center', |
|||
columnWidth: 120, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'crdOri', |
|||
columnLabel: 'Original CRD', |
|||
align: 'center', |
|||
columnWidth: 120, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'inspection', |
|||
columnLabel: 'Inspection Date', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'realCrd', |
|||
columnLabel: 'Actual Completion Date', |
|||
align: 'center', |
|||
columnWidth: 150, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'eta', |
|||
columnLabel: 'ETA', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'flexid', |
|||
columnLabel: 'Flexport Id', |
|||
align: 'center', |
|||
columnWidth: 90, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'obd', |
|||
columnLabel: 'On Board Date', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'docSent', |
|||
columnLabel: 'Doc Sent', |
|||
align: 'center', |
|||
columnWidth: 90, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'telexRelease', |
|||
columnLabel: 'Telex Release', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'advancePayment', |
|||
columnLabel: 'Advance Payment', |
|||
align: 'center', |
|||
columnWidth: 120, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'advancePaid', |
|||
columnLabel: 'Advanc Paid', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'createTime', |
|||
columnLabel: 'Create Date', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'planner', |
|||
columnLabel: 'M-Planner', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'edit', |
|||
columnLabel: 'Edit Date', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'endPlanner', |
|||
columnLabel: 'Last Editor', |
|||
align: 'center', |
|||
columnWidth: 100, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'remarkDelay', |
|||
columnLabel: 'Remark Delay', |
|||
align: 'center', |
|||
columnWidth: 110, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'remark', |
|||
columnLabel: 'Comments', |
|||
align: 'center', |
|||
columnWidth: 180, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
}, |
|||
{ |
|||
columnProp: 'inspectionCompletedQty', |
|||
columnLabel: 'Inspection Completed Qty', |
|||
align: 'center', |
|||
columnWidth: 140, |
|||
showOverflowTooltip: true, |
|||
headerAlign: 'center' |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
computed: { |
|||
visibleColumns() { |
|||
const source = this.baseColumnList || this.columnList |
|||
const applied = applyFieldSchemaToColumns(source, this.fieldSchemaFields) |
|||
return applied.filter(c => !c.columnHidden) |
|||
} |
|||
}, |
|||
created() { |
|||
this.baseColumnList = JSON.parse(JSON.stringify(this.columnList)) |
|||
}, |
|||
mounted() { |
|||
this.updateTableHeight() |
|||
window.addEventListener('resize', this.onWindowResize) |
|||
}, |
|||
activated () { |
|||
this.updateTableHeight() |
|||
this.refreshTableLayout() |
|||
}, |
|||
deactivated () { |
|||
this.refreshTableLayout() |
|||
}, |
|||
beforeDestroy () { |
|||
window.removeEventListener('resize', this.onWindowResize) |
|||
}, |
|||
methods: { |
|||
onWindowResize () { |
|||
this.updateTableHeight() |
|||
}, |
|||
updateTableHeight () { |
|||
const calculatedHeight = (window.innerHeight - 220) / 2 |
|||
this.height = calculatedHeight > 220 ? calculatedHeight : 220 |
|||
this.refreshTableLayout() |
|||
}, |
|||
refreshTableLayout () { |
|||
this.$nextTick(() => { |
|||
if (this.$refs.poTable && this.$refs.poTable.doLayout) { |
|||
this.$refs.poTable.doLayout() |
|||
} |
|||
}) |
|||
}, |
|||
formatColumnCell (row, item) { |
|||
if (item.columnProp === 'orderType') { |
|||
return formatPoOrderTypeLabel(row.orderType) |
|||
} |
|||
const prop = item && item.columnProp |
|||
if (!prop || !row) { |
|||
return '' |
|||
} |
|||
if (row[prop] !== undefined && row[prop] !== null) { |
|||
return row[prop] |
|||
} |
|||
if (row.extValues && typeof row.extValues === 'object' && |
|||
Object.prototype.hasOwnProperty.call(row.extValues, prop)) { |
|||
return row.extValues[prop] |
|||
} |
|||
return '' |
|||
}, |
|||
|
|||
buildQueryRequest() { |
|||
return buildPoOrderQueryParams({ |
|||
searchData: this.searchData, |
|||
advancedQueryData: this.advancedQueryData, |
|||
page: this.pageIndex, |
|||
limit: this.pageSize |
|||
}) |
|||
}, |
|||
|
|||
handleSearch() { |
|||
if (!this.searchData.customer) { |
|||
this.$message.warning('Please select Customer first') |
|||
return |
|||
} |
|||
this.pageIndex = 1 |
|||
this.getDataList() |
|||
}, |
|||
|
|||
onSessionCustomerChange (customer) { |
|||
this.searchData.customer = customer |
|||
this.advancedQueryData.rows = [] |
|||
this.pageIndex = 1 |
|||
this.dataList = [] |
|||
this.totalPage = 0 |
|||
this.currentRow = {} |
|||
this.clearDetailTabs() |
|||
if (!customer) { |
|||
this.fieldSchemaFields = [] |
|||
this.advancedQueryData.rows = [] |
|||
this.refreshTableLayout() |
|||
return |
|||
} |
|||
this.loadFieldSchema(customer).then(() => { |
|||
this.getDataList() |
|||
}) |
|||
}, |
|||
|
|||
loadFieldSchema (customer) { |
|||
return getPoFieldSchema({ |
|||
site: this.searchData.site, |
|||
customer, |
|||
scene: 'list' |
|||
}).then(({ data }) => { |
|||
if (data && data.code === 0 && data.data) { |
|||
this.fieldSchemaFields = data.data.fields || [] |
|||
const queryFields = getAdvancedQueryFieldsFromSchema(this.fieldSchemaFields) |
|||
this.advancedQueryData.rows = createAdvancedQueryDataFromSchema(queryFields).rows |
|||
} else { |
|||
this.fieldSchemaFields = [] |
|||
this.advancedQueryData.rows = [] |
|||
this.$message.error((data && data.msg) || 'Failed to load field permissions') |
|||
} |
|||
this.refreshTableLayout() |
|||
}).catch(() => { |
|||
this.fieldSchemaFields = [] |
|||
this.advancedQueryData.rows = [] |
|||
this.$message.error('Failed to load field permissions') |
|||
this.refreshTableLayout() |
|||
}) |
|||
}, |
|||
|
|||
handleListResponse(data) { |
|||
if (data.code === 0) { |
|||
this.dataList = ((data.page && data.page.list) || []).map(row => normalizeSchemaRowValues(row)) |
|||
this.pageIndex = data.page.currPage |
|||
this.pageSize = data.page.pageSize |
|||
this.totalPage = data.page.totalCount |
|||
|
|||
if (this.dataList.length > 0) { |
|||
this.$nextTick(() => { |
|||
if (this.$refs.poTable) { |
|||
this.$refs.poTable.setCurrentRow(this.dataList[0]) |
|||
} |
|||
this.changeData(this.dataList[0]) |
|||
}) |
|||
} else { |
|||
this.currentRow = {} |
|||
this.clearDetailTabs() |
|||
} |
|||
} else { |
|||
this.$message.error((data && data.msg) || 'Failed to get list') |
|||
} |
|||
}, |
|||
|
|||
getDataList() { |
|||
if (!this.searchData.customer) { |
|||
this.loading = false |
|||
this.dataList = [] |
|||
this.totalPage = 0 |
|||
this.currentRow = {} |
|||
this.clearDetailTabs() |
|||
this.refreshTableLayout() |
|||
return |
|||
} |
|||
this.loading = true |
|||
const { params, useAdvanced } = this.buildQueryRequest() |
|||
const request = useAdvanced ? searchPoDetailAdvancedPage(params) : searchPoDetailPage(params) |
|||
request.then(({ data }) => { |
|||
this.handleListResponse(data) |
|||
this.loading = false |
|||
this.refreshTableLayout() |
|||
}).catch(() => { |
|||
this.loading = false |
|||
this.$message.error('Request failed') |
|||
this.refreshTableLayout() |
|||
}) |
|||
}, |
|||
|
|||
/** External reset: only clears top basic conditions, not advancedQueryData */ |
|||
resetSearch() { |
|||
const currentCustomer = this.searchData.customer |
|||
this.searchData = { |
|||
site: this.$store.state.user.site, |
|||
customer: currentCustomer, |
|||
buyer: '', |
|||
poNo: '', |
|||
orderType: '', |
|||
partNo: '', |
|||
supplierNo: '', |
|||
sku: '', |
|||
status: '', |
|||
supplierName: '', |
|||
feeDateStart: '', |
|||
feeDateEnd: '' |
|||
} |
|||
this.pageIndex = 1 |
|||
this.getDataList() |
|||
}, |
|||
|
|||
openSearchBaseList (val) { |
|||
this.eamTagNo = val |
|||
let strVal = '' |
|||
let conSql = '' |
|||
if (val === 520) { |
|||
strVal = this.searchData.supplierNo || '' |
|||
conSql = " and supplier_no <> '' " |
|||
} else if (val === 2017) { |
|||
strVal = this.searchData.partNo || '' |
|||
conSql = " and part_no <> '' " |
|||
} |
|||
this.$nextTick(() => { |
|||
this.$refs.eamList.init(val, strVal, conSql) |
|||
}) |
|||
}, |
|||
|
|||
getEamData (val) { |
|||
if (this.eamTagNo === 520) { |
|||
this.searchData.supplierNo = val.supplier_no || val.code || '' |
|||
this.searchData.supplierName = val.supplier_name || val.name || '' |
|||
} else if (this.eamTagNo === 2017) { |
|||
this.searchData.partNo = val.part_no || val.code || '' |
|||
} |
|||
this.eamTagNo = '' |
|||
}, |
|||
// Export |
|||
exportExcel () { |
|||
if (!this.searchData.customer) { |
|||
this.$message.warning('Please select Customer first') |
|||
return |
|||
} |
|||
const now = new Date() |
|||
const year = now.getFullYear() |
|||
const month = String(now.getMonth() + 1).padStart(2, '0') |
|||
const day = String(now.getDate()).padStart(2, '0') |
|||
const hour = String(now.getHours()).padStart(2, '0') |
|||
const minute = String(now.getMinutes()).padStart(2, '0') |
|||
const second = String(now.getSeconds()).padStart(2, '0') |
|||
const exportName = `PO Order List ${year}${month}${day}${hour}${minute}${second}` |
|||
|
|||
const { params, useAdvanced } = buildPoOrderQueryParams({ |
|||
searchData: this.searchData, |
|||
advancedQueryData: this.advancedQueryData, |
|||
page: 1, |
|||
limit: 99999 |
|||
}) |
|||
|
|||
try { |
|||
excel.exportTable({ |
|||
url: useAdvanced ? 'pODetail/advancedPage' : 'pODetail/page', |
|||
columnMapping: this.visibleColumns, |
|||
mergeSetting: [], |
|||
params, |
|||
fileName: exportName + '.xlsx', |
|||
rowFetcher: res => { |
|||
const page = res.data && res.data.page |
|||
const rows = ((page && page.list) || []).map(row => normalizeSchemaRowValues(row)) |
|||
return { rows } |
|||
}, |
|||
columnFormatter: [], |
|||
dropColumns: [] |
|||
}) |
|||
} catch (error) { |
|||
this.$message.error('Export failed: ' + error.message) |
|||
} |
|||
}, |
|||
|
|||
// Page size |
|||
sizeChangeHandle(val) { |
|||
this.pageSize = val |
|||
this.pageIndex = 1 |
|||
this.getDataList() |
|||
}, |
|||
|
|||
// Current page |
|||
currentChangeHandle(val) { |
|||
this.pageIndex = val |
|||
this.getDataList() |
|||
}, |
|||
|
|||
// Row click event (similar to supplierList.vue changeData pattern) |
|||
changeData(row) { |
|||
if (!row) { |
|||
this.currentRow = {} |
|||
this.clearDetailTabs() |
|||
return |
|||
} |
|||
this.currentRow = JSON.parse(JSON.stringify(row)) |
|||
this.refreshCurrentTabTable() |
|||
}, |
|||
|
|||
// Refresh current tab table data (similar to supplierList.vue refreshCurrentTabTable) |
|||
refreshCurrentTabTable() { |
|||
if (!this.hasCurrentRowData()) { |
|||
this.clearDetailTabs() |
|||
return |
|||
} |
|||
if (this.activeTab === 'orderDetail') { |
|||
// Order detail does not need refresh, display currentRow directly |
|||
} |
|||
if (this.activeTab === 'logistics') { |
|||
this.refreshLogisticsTable() |
|||
} |
|||
if (this.activeTab === 'inspectionDetail') { |
|||
this.refreshInspectionTable() |
|||
} |
|||
if (this.activeTab === 'partAttribute') { |
|||
this.refreshPartAttribute() |
|||
} |
|||
}, |
|||
getDetailTabHeight () { |
|||
return Number(this.height) - 20 |
|||
}, |
|||
hasCurrentRowData () { |
|||
return !!(this.currentRow && typeof this.currentRow === 'object' && Object.keys(this.currentRow).length > 0) |
|||
}, |
|||
clearDetailTabs () { |
|||
const site = this.searchData.site || this.$store.state.user.site |
|||
const height = this.getDetailTabHeight() |
|||
if (this.$refs.logisticsPoList && this.$refs.logisticsPoList.init) { |
|||
this.$refs.logisticsPoList.init({ |
|||
flexId: '', |
|||
supplierNo: '', |
|||
site, |
|||
height |
|||
}) |
|||
} |
|||
if (this.$refs.inspectionDetailList && this.$refs.inspectionDetailList.init) { |
|||
this.$refs.inspectionDetailList.init({ |
|||
site, |
|||
orderNo: '', |
|||
itemNo: null, |
|||
height |
|||
}) |
|||
} |
|||
if (this.$refs.partAttributeTab && this.$refs.partAttributeTab.init) { |
|||
this.$refs.partAttributeTab.init({ |
|||
site, |
|||
partNo: '', |
|||
codeNo: '', |
|||
functionType: 'P', |
|||
height |
|||
}) |
|||
} |
|||
}, |
|||
|
|||
// Refresh logistics tab table (similar to supplierList.vue refreshShareTable) |
|||
refreshLogisticsTable() { |
|||
if (!this.hasCurrentRowData()) { |
|||
this.clearDetailTabs() |
|||
return |
|||
} |
|||
let inData = { |
|||
flexId: this.currentRow.flexid, |
|||
supplierNo: this.currentRow.supplierNo, |
|||
site: this.$store.state.user.site, |
|||
height: this.getDetailTabHeight() |
|||
} |
|||
this.$refs.logisticsPoList.init(inData) |
|||
}, |
|||
|
|||
// Refresh inspection detail tab table |
|||
refreshInspectionTable() { |
|||
if (!this.hasCurrentRowData()) { |
|||
this.clearDetailTabs() |
|||
return |
|||
} |
|||
let inData = { |
|||
site: this.$store.state.user.site, |
|||
orderNo: this.currentRow.orderNo || '', |
|||
itemNo: this.currentRow.itemNo || null, |
|||
height: this.getDetailTabHeight() |
|||
} |
|||
this.$refs.inspectionDetailList.init(inData) |
|||
}, |
|||
refreshPartAttribute () { |
|||
if (!this.hasCurrentRowData()) { |
|||
this.clearDetailTabs() |
|||
return |
|||
} |
|||
const site = this.currentRow.site || this.$store.state.user.site |
|||
const partNo = this.currentRow.partNo || '' |
|||
const inData = { |
|||
site, |
|||
partNo, |
|||
codeNo: this.currentRow.codeNo || '', |
|||
functionType: 'P', |
|||
height: this.getDetailTabHeight() |
|||
} |
|||
if (!partNo) { |
|||
this.initPartAttributeTab(inData) |
|||
return |
|||
} |
|||
if (inData.codeNo) { |
|||
this.initPartAttributeTab(inData) |
|||
return |
|||
} |
|||
searchPartInfo({ site, partNo }).then(({ data }) => { |
|||
const codeNo = (data && data.code === 0 && data.data) |
|||
? (data.data.codeNo || data.data.code_no || '') |
|||
: '' |
|||
this.$set(this.currentRow, 'codeNo', codeNo) |
|||
this.initPartAttributeTab({ |
|||
...inData, |
|||
codeNo |
|||
}) |
|||
}).catch(() => { |
|||
this.initPartAttributeTab(inData) |
|||
}) |
|||
}, |
|||
initPartAttributeTab (inData) { |
|||
if (this.$refs.partAttributeTab && this.$refs.partAttributeTab.init) { |
|||
this.$refs.partAttributeTab.init(inData) |
|||
} |
|||
}, |
|||
|
|||
// Tab click event (similar to supplierList.vue tabClick) |
|||
handleTabClick(tab, event) { |
|||
this.refreshCurrentTabTable() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.el-table /deep/ .cell { |
|||
height: auto; |
|||
line-height: 1.5; |
|||
} |
|||
|
|||
/deep/ .customer-tab .el-tabs__content { |
|||
padding: 5px !important; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue