@@ -39,43 +39,57 @@
< div class = "form-actions" > < el-button size = "large" @click ="resetForm" > 重置 < / el -button > < el-button type = "primary" size = "large" :loading = "submitting" @click ="completeRepair" > 完成维修 < / el -button > < / div >
< / main >
< aside class = "side-column" > < section class = "panel operator-panel" > < h2 > 当前操作人 < / h2 > < div > < span > 姓名 < / span > < strong > { { currentUser . name || '-' } } < / strong > < / div > < div > < span > 工号 < / span > < strong > { { currentUser . code || '-' } } < / strong > < / div > < div > < span > 当前任务 < / span > < strong > { { task ? . device _no || '未选择' } } < / strong > < / div > < / section > < section class = "panel tip-panel" > < h2 > 处理提示 < / h2 > < p > 物料不良请登记替换备件 ; 作业不良需选择责任人员 ; 搭配错误需选择对应物料分类 。 < / p > < el-button link type = "primary" @click ="goTasks" > 查看待维修订单 < / el -button > < / section > < / aside >
< aside class = "side-column" > < section class = "panel operator-panel" > < h2 > 当前操作人 < / h2 > < div > < span > 用户编码 < / span > < el-input v-model = "userCode" size="small" clearable placeholder="请输入用户编码" @blur="checkUserCode" @keyup.enter="checkUserCode" /></div><div><span>姓名</span><strong>{{ userName || '-' }}</strong></div><div><span>当前任务</span><strong>{{ task?.device_no || '未选择' }}</strong></div><p v-if="userCodeError" class="field-error">{{ userCodeError }}</p></section><section class="panel tip-panel"><h2>处理提示</h2><p> 物料不良请登记替换备件; 作业不良需选择责任人员; 搭配错误需选择对应物料分类。</p><el-button link type= "primary" @click="goTasks"> 查看待维修订单 < / el -button > < / section > < / aside >
< / div >
< / div >
< el-dialog v-model = "partDialogVisible" title="添加 维修备件" width="4 60px"><el-input v-model="partCode" autofocus placeholder="请输入 商品编码" @keyup.enter="addPart" /><template #footer><el-button @click="partDialogVisible = false">取消</el-button ><el-button type="primary" :loading="loadingPart" @click="addPart " > 确定 < / el -button > < / template > < / el-dialog >
< el-dialog v-model = "partDialogVisible" title="选择 维修备件" width="7 60px" class="material-dialog" @closed="resetMaterialSearch"><div class="material-search"><el-input v-model="materialProductCode" clearable autofocus placeholder="商品编码" @keyup.enter="searchMaterialList" /><el-input v-model="materialProductName" clearable placeholder="商品名称" @keyup.enter="searchMaterialList" /><el-select v-model="materialCategoryId" clearable filterable placeholder="物料分类" @change="searchMaterialList"><el-option v-for="item in categories" :key="item.id" :label="item.category_name" :value="String(item.id)" /></el-select><el-button type="primary" :loading="materialLoading" @click="searchMaterialList">搜索</el-button></div><div class="material-hint">可按编码、名称或物料分类筛选,已添加的备件会自动标记。</div><el-table v-loading="materialLoading" :data="materialItems" border stripe class="material-table"><el-table-column prop="product_code" label="商品编码" min-width="180" /><el-table-column prop="product_name" label="商品名称" min-width="220" show-overflow-tooltip /><el-table-column prop="category_name" label="物料分类" min-width="140"><template #default="scope">{{ scope.row.category_name || '-' }}</template></el-table-column><el-table-column label="操作" width="100" fixed="right"><template #default="scope" ><el-button link type="primary" :disabled="isPartAdded(scope.row.product_code)" @click="selectMaterial(scope.row)">{{ isPartAdded(scope.row.product_code) ? '已添加' : '选择' }}</el-button></template></el-table-column></el-table><el-empty v-if="!materialLoading && !materialItems.length" description="暂无匹配的备件" :image-size="72" /><div class="material-pagination"><el-pagination v-model:current-page="materialPage" v-model:page-size="materialLimit" layout="total, prev, pager, next" :total="materialTotal" :page-sizes="[10, 20, 50]" @current-change="searchMaterialList" @size-change="handleMaterialSizeChange" /></div><template #footer><el-button @click="partDialogVisible = false " > 关闭 < / el -button > < / template > < / el-dialog >
< / div >
< / template >
< script setup lang = "ts" >
import { CircleCheckFilled , Grid , EditPen , Tools , Box } from '@element-plus/icons-vue'
import { CircleCheckFilled , Grid , EditPen , Tools , Box , Search } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import type { UploadUserFile } from 'element-plus'
import { computed , onMounted , ref } from 'vue'
import { navigateTo , useRoute } from 'nuxt/app'
import { useMemberStore } from '~/stores/member'
import { getFaultDescriptionOptions , getMaterialCategories , getRepairStatistics , getRepairTask , getScanRecords , lookupMaterial , submitRepairRecord , uploadProduceImage , type ProduceRepairTask } from '~/apps/produce/api/exception'
import { checkMemberUser , getFaultDescriptionOptions , getMaterialCategories , getRepairStatistics , getRepairTask , getScanRecords , searchMaterials , submitRepairRecord , uploadProduceImage , type ProduceRepairTask , type ProduceScanRecord } from '~/apps/produce/api/exception'
interface Part { id : string ; product _code : string ; product _name ? : string ; category _id ? : string | number ; category _name ? : string ; source : string ; quantity : number ; fault _description _ids : string [ ] }
interface ScanRecord { id : string | number ; process _name ? : string ; step _name ? : string ; operator ? : string ; user _code ? : string }
interface FaultDescription { id : string | number ; category _id : string | number ; description : string }
interface MaterialOption { id : string | number ; product _code : string ; product _name : string ; category _id : string | number ; category _name : string }
const memberStore = useMemberStore ( )
const currentUser = computed ( ( ) => ( { name : String ( memberStore . info ? . nickname || memberStore . info ? . real _name || memberStore . info ? . username || '' ) , code : String ( memberStore . info ? . username || memberStore . info ? . user _code || '' ) } ) )
const userCode = ref ( '' )
const userName = ref ( '' )
const userCodeError = ref ( '' )
const summaries = ref ( [ { label : '待维修' , value : 0 , type : 'warning' , action : true } , { label : '处理中' , value : 0 , type : 'primary' } , { label : '今日完成' , value : 0 , type : 'success' } ] )
const resultOptions = [ { label : '物料不良' , value : 'material_defect' , desc : '物料本身存在异常' , icon : Box } , { label : '作业不良' , value : 'operation_defect' , desc : '作业过程导致异常' , icon : EditPen } , { label : '搭配错误' , value : 'assembly_mismatch' , desc : '物料搭配或装配错误' , icon : Grid } ]
const deviceNo = ref ( '' )
const task = ref < ProduceRepairTask | null > ( null )
const categories = ref < Array < { id : string | number ; category_name : string } > > ( [ ] )
const scanRecords = ref < ScanRecord [ ] > ( [ ] )
const scanRecords = ref < ProduceScanRecord [ ] > ( [ ] )
const faults = ref < FaultDescription [ ] > ( [ ] )
const imageFiles = ref < UploadUserFile [ ] > ( [ ] )
const form = ref ( { repair _result : 'material_defect' , category _ids : [ ] as string [ ] , responsible _ids : [ ] as string [ ] , parts : [ ] as Part [ ] , remark : '' } )
const loadingTask = ref ( false )
const loadingPart = ref ( false )
const submitting = ref ( false )
const partDialogVisible = ref ( false )
const partCode = ref ( '' )
const materialProductCode = ref ( '' )
const materialProductName = ref ( '' )
const materialCategoryId = ref < string | number > ( '' )
const materialItems = ref < MaterialOption [ ] > ( [ ] )
const materialPage = ref ( 1 )
const materialLimit = ref ( 10 )
const materialTotal = ref ( 0 )
const materialLoading = ref ( false )
const reasonText = computed ( ( ) => [ task . value ? . reason _name , task . value ? . issue _name ] . filter ( Boolean ) . join ( ' · ' ) || '-' )
const checkUserCode = async ( ) => {
const value = userCode . value . trim ( )
if ( ! value ) { userCodeError . value = '请输入用户编码' ; userName . value = '' ; return false }
try { const result = await checkMemberUser ( value ) ; userName . value = result ? . nickname || result ? . username || '' ; userCodeError . value = '' ; return true } catch ( error : any ) { userCodeError . value = error ? . message || '用户编码不存在' ; userName . value = '' ; return false }
}
const loadStatistics = async ( ) => {
const data = await getRepairStatistics ( { user _code : currentUser . value . code } ) . catch ( ( ) => null )
@@ -88,18 +102,38 @@ const loadStatistics = async () => {
}
const loadTask = async ( ) => { const value = deviceNo . value . trim ( ) ; if ( ! value || loadingTask . value ) return ElMessage . warning ( '请输入设备编码或订单号' ) ; loadingTask . value = true ; try { task . value = await getRepairTask ( value ) ; form . value . responsible _ids = [ ] ; scanRecords . value = [ ] ; if ( task . value ? . device _no ) { const result = await getScanRecords ( { order _no : task . value . device _no , limit : 50 } ) ; scanRecords . value = Array . isArray ( result ? . items ) ? result . items : [ ] ; } } finally { loadingTask . value = false } }
const selectResult = ( value : string ) => { form . value . repair _result = value ; if ( value !== 'assembly_mismatch' ) form . value . category _ids = [ ] ; if ( value !== 'operation_defect' ) form . value . responsible _ids = [ ] }
const openPartDialog = ( ) => { partCode . value = '' ; partDialogVisible . value = true }
const addPart = async ( ) => { const code = partCode . value . trim ( ) ; if ( ! code ) return ElMessage . warning ( '请输入商品编码' ) ; if ( form . value . parts . some ( ( item : Part ) => item . product _code === code ) ) return ElMessage . warning ( '该物料已添加' ) ; loadingPart . value = true ; try { const material = await lookupMaterial ( code ) ; const part : Part = { id : ` ${ Date . now ( ) } - ${ code } ` , product _code : material . product _code || code , product _name : material . product _name , category _id : material . category _id , category _name : material . category _name , source : 'new' , quantity : 1 , fault _description _ids : [ ] } ; form . value . parts . push ( part ) ; await loadFaults ( ) ; partDialogVisible . value = false } finally { loadingPart . value = false } }
const openPartDialog = ( ) => { materialProductCode . value = '' ; materialProductName . value = '' ; materialCategoryId . value = '' ; materialPage . value = 1 ; partDialogVisible . value = true ; void searchMaterialList ( ) }
const searchMaterialList = async ( ) => { materialLoading . value = true ; try { const result = await searchMaterials ( materialProductCode . value , materialProductName . value , materialCategoryId . value , materialPage . value , materialLimit . value ) ; materialItems . value = Array . isArray ( result ? . items ) ? result . items : [ ] ; materialTotal . value = Number ( result ? . total || 0 ) } finally { materialLoading . value = false } }
const handleMaterialSizeChange = ( size : number ) => { materialLimit . value = size ; materialPage . value = 1 ; void searchMaterialList ( ) }
const isPartAdded = ( productCode : string ) => form . value . parts . some ( ( item : Part ) => item . product _code === productCode )
const appendMaterial = async ( material : MaterialOption ) => { if ( isPartAdded ( material . product _code ) ) return ElMessage . warning ( '该物料已添加' ) ; const part : Part = { id : ` ${ Date . now ( ) } - ${ material . product _code } ` , product _code : material . product _code , product _name : material . product _name , category _id : material . category _id , category _name : material . category _name , source : 'new' , quantity : 1 , fault _description _ids : [ ] } ; form . value . parts . push ( part ) ; await loadFaults ( ) ; ElMessage . success ( '备件已添加' ) }
const selectMaterial = ( material : MaterialOption ) => { void appendMaterial ( material ) }
const resetMaterialSearch = ( ) => { materialProductCode . value = '' ; materialProductName . value = '' ; materialCategoryId . value = '' ; materialItems . value = [ ] ; materialPage . value = 1 ; materialTotal . value = 0 }
const loadFaults = async ( ) => { const ids = [ ... new Set ( form . value . parts . map ( ( item : Part ) => String ( item . category _id || '' ) ) . filter ( Boolean ) ) ] ; faults . value = ids . length ? await getFaultDescriptionOptions ( ids ) : [ ] }
const faultsForPart = ( part : Part ) => faults . value . filter ( ( item : FaultDescription ) => String ( item . category _id ) === String ( part . category _id ) )
const removePart = ( index : number ) => { form . value . parts . splice ( index , 1 ) ; void loadFaults ( ) }
const handleImageExceed = ( ) => ElMessage . warning ( '最多上传 4 张图片' )
const resetForm = ( ) => { deviceNo . value = '' ; task . value = null ; scanRecords . value = [ ] ; form . value = { repair _result : 'material_defect' , category _ids : [ ] , responsible _ids : [ ] , parts : [ ] , remark : '' } ; imageFiles . value = [ ] }
const completeRepair = async ( ) => { if ( ! task . value ? . id ) return ElMessage . warning ( '请先查询有效的维修任务' ) ; if ( ! currentUser . value . code ) return ElMessage . warning ( '请先登录' ) ; if ( form . value . repair _result === 'assembly_mismatch' && ! form . value . category _ids . length ) return ElMessage . warning ( '请选择搭配错误分类' ) ; if ( form . value . repair _result === 'operation_defect' && ! form . value . responsible _ids . length ) return ElMessage . warning ( '请选择责任人员' ) ; submitting . value = true ; try { const images : string [ ] = [ ] ; for ( const file of imageFiles . value ) if ( file . raw ) { const url = await uploadProduceImage ( file . raw , 'repair' ) ; if ( url ) images . push ( url ) } const response = await submitRepairRecord ( { exception _id : task . value . id , user _code : currentUser . value . code , repair _result : form . value . repair _result , images , category _ids : form . value . category _ids , parts : form . value . parts . map ( ( part : Part ) => ( { product _code : part . product _code , source : part . source , quantity : part . quantity , fault _description _ids : part . fault _description _ids } ) ) , operation _fault _steps : form . value . responsible _ids , responsible _operators : form . value . responsible _ids , remark : form . value . remark . trim ( ) } ) ; if ( response ? . code !== 0 ) { ElMessage . error ( response ? . msg || '维修提交失败' ) ; return } ElMessage . success ( '维修记录已完成' ) ; resetForm ( ) ; void loadStatistics ( ) } finally { submitting . value = false } }
const completeRepair = async ( ) => { if ( ! task . value ? . id ) return ElMessage . warning ( '请先查询有效的维修任务' ) ; if ( ! await checkUserCode ( ) ) return ElMessage . warning ( userCodeError . value ) ; if ( form . value . repair _result === 'assembly_mismatch' && ! form . value . category _ids . length ) return ElMessage . warning ( '请选择搭配错误分类' ) ; if ( form . value . repair _result === 'operation_defect' && ! form . value . responsible _ids . length ) return ElMessage . warning ( '请选择责任人员' ) ; submitting . value = true ; try { const images : string [ ] = [ ] ; for ( const file of imageFiles . value ) if ( file . raw ) { const url = await uploadProduceImage ( file . raw , 'repair' ) ; if ( url ) images . push ( url ) } const selectedScanIds = scanRecords . value . filter ( record => form . value . responsible _ids . includes ( String ( record . id ) ) ) . map ( record => record . id ) ; const response = await submitRepairRecord ( { exception _id : task . value . id , user _code : userCode . value . trim ( ) , repair _result : form . value . repair _result , images , category _ids : form . value . category _ids , parts : form . value . parts . map ( ( part : Part ) => ( { product _code : part . product _code , source : part . source , quantity : part . quantity , fault _description _ids : part . fault _description _ids } ) ) , operation _fault _steps : selectedScanIds , responsible _operators : selectedScanIds , remark : form . value . remark . trim ( ) } ) ; if ( response ? . code !== 0 ) { ElMessage . error ( response ? . msg || '维修提交失败' ) ; return } ElMessage . success ( '维修记录已完成' ) ; resetForm ( ) ; void loadStatistics ( ) } finally { submitting . value = false } }
const goTasks = ( ) => navigateTo ( '/produce/repair/tasks' )
onMounted ( ( ) => { void loadStatistics ( ) ; void getMaterialCategories ( ) . then ( ( data : Array < { id : string | number ; category _name : string } > ) => { categories . value = Array . isArray ( data ) ? data : [ ] } ) ; const query = useRoute ( ) . query . device _no ; if ( query ) { deviceNo . value = String ( query ) ; void loadTask ( ) } } )
onMounted ( ( ) => { userCode . value = currentUser . value . code ; userName . value = currentUser . value . name ; void checkUserCode ( ) ; void loadStatistics ( ) ; void getMaterialCategories ( ) . then ( ( data : Array < { id : string | number ; category _name : string } > ) => { categories . value = Array . isArray ( data ) ? data : [ ] } ) ; const query = useRoute ( ) . query . device _no ; if ( query ) { deviceNo . value = String ( query ) ; void loadTask ( ) } } )
< / script >
< style scoped >
. produce - work - page { min - height : calc ( 100 vh - 60 px ) ; padding : 28 px ; background : # f5f7fb ; color : # 17233 d } . page - shell { max - width : 1440 px ; margin : 0 auto } . page - hero { display : flex ; align - items : center ; justify - content : space - between ; padding : 32 px 36 px ; border - radius : 22 px ; color : # fff ; box - shadow : 0 14 px 32 px rgba ( 37 , 99 , 235 , .12 ) } . repair - hero { background : linear - gradient ( 135 deg , # 2 f6cf6 , # 35 bfa3 ) } . eyebrow { font - size : 13 px ; opacity : .85 } h1 { margin : 8 px 0 0 ; font - size : 30 px } . page - hero p { margin : 8 px 0 0 ; opacity : .86 } . summary - grid { display : grid ; grid - template - columns : repeat ( 3 , 1 fr ) ; gap : 16 px ; margin : 20 px 0 } . summary - card , . panel { background : # fff ; border : 1 px solid # e7edf5 ; border - radius : 18 px ; box - shadow : 0 8 px 24 px rgba ( 36 , 59 , 92 , .04 ) } . summary - card { display : flex ; align - items : center ; gap : 12 px ; padding : 18 px 22 px } . summary - card strong { font - size : 28 px } . summary - card span { color : # 8 a94a6 ; font - size : 13 px } . summary - card . el - button { margin - left : auto } . warning { color : # e59a2f } . primary { color : # 2563 eb } . success { color : # 26 b36c } . content - grid { display : grid ; grid - template - columns : minmax ( 0 , 1 fr ) 350 px ; gap : 20 px ; align - items : start } . main - column , . side - column { display : flex ; flex - direction : column ; gap : 20 px } . panel { padding : 26 px } . panel - title { display : flex ; align - items : flex - start ; gap : 14 px } . panel - title > span { display : flex ; align - items : center ; justify - content : center ; width : 30 px ; height : 30 px ; border - radius : 50 % ; background : # eaf2ff ; color : # 2563 eb ; font - weight : 700 ; flex : none } . panel - title h2 { margin : 0 ; font - size : 17 px } . panel - title p { margin : 6 px 0 0 ; color : # 9 aa4b4 ; font - size : 13 px } . panel - title em { margin - left : auto ; padding : 5 px 10 px ; border - radius : 999 px ; color : # 2563 eb ; background : # edf4ff ; font - size : 12 px ; font - style : normal } . panel - title em . optional { color : # 8793 a6 ; background : # f3f5f8 } . panel - title small { margin - left : auto ; color : # 9 aa4b4 } . inline - form { display : flex ; gap : 12 px ; margin - top : 20 px } . inline - form . el - input { flex : 1 } . task - found { display : flex ; align - items : center ; gap : 12 px ; margin - top : 16 px ; padding : 14 px ; border - radius : 12 px ; background : # f0fbf6 ; color : # 26 b36c } . task - found > div { display : flex ; flex - direction : column ; gap : 4 px ; flex : 1 } . task - found span { color : # 2 b3853 ; font - weight : 600 } . task - found . el - tag { margin - left : auto } . info - grid { display : grid ; grid - template - columns : repeat ( 3 , 1 fr ) ; gap : 14 px ; margin - top : 22 px } . info - grid div { padding : 14 px ; border - radius : 12 px ; background : # f8fafc } . info - grid span , . info - grid strong { display : block } . info - grid span { color : # 9 aa4b4 ; font - size : 12 px } . info - grid strong { margin - top : 8 px ; font - size : 14 px ; word - break : break - all } . result - grid { display : grid ; grid - template - columns : repeat ( 3 , 1 fr ) ; gap : 14 px ; margin - top : 20 px } . result - card { display : flex ; flex - direction : column ; align - items : flex - start ; gap : 8 px ; padding : 18 px ; border : 1 px solid # e6edf5 ; border - radius : 14 px ; background : # f8fafc ; color : # 56647 a ; text - align : left ; cursor : pointer } . result - card . active { border - color : # 409 eff ; background : # edf4ff ; color : # 2563 eb } . result - card small { color : # 9 aa4b4 } . category - grid , . responsibility - grid { display : flex ; flex - wrap : wrap ; gap : 14 px ; margin - top : 22 px } . responsibility - grid . el - checkbox { height : auto ; margin : 0 ; padding : 12 px 16 px ; border : 1 px solid # e6edf5 ; border - radius : 12 px ; background : # f8fafc } . responsibility - grid . el - checkbox . is - checked { border - color : # 409 eff ; background : # edf4ff } . responsibility - grid small { display : block ; color : # 9 aa4b4 } . part - toolbar { display : flex ; justify - content : space - between ; align - items : center ; margin : 22 px 0 12 px } . part - row { display : flex ; align - items : flex - start ; gap : 12 px ; padding : 16 px 0 ; border - bottom : 1 px solid # eef2f7 } . part - index { display : flex ; align - items : center ; justify - content : center ; width : 28 px ; height : 28 px ; border - radius : 50 % ; background : # edf4ff ; color : # 2563 eb } . part - info { display : flex ; flex - direction : column ; gap : 8 px ; flex : 1 } . part - info > span { color : # 8 a94a6 ; font - size : 12 px } . fault - select { width : 100 % } . remark - input { margin - top : 18 px } . form - actions { display : flex ; justify - content : flex - end ; gap : 12 px } . operator - panel h2 , . tip - panel h2 { margin : 0 0 18 px } . operator - panel div { display : flex ; justify - content : space - between ; padding : 13 px 0 ; border - bottom : 1 px solid # eef2f7 ; font - size : 13 px } . operator - panel div : last - child { border : 0 } . operator - panel span { color : # 9 aa4b4 } . tip - panel p { color : # 718096 ; font - size : 13 px ; line - height : 1.8 } . upload - plus { font - size : 30 px ; color : # 409 eff } : deep ( . el - upload -- picture - card ) , : deep ( . el - upload - list _ _item ) { width : 92 px ; height : 92 px } @ media ( max - width : 900 px ) { . produce - work - page { padding : 16 px } . content - grid { grid - template - columns : 1 fr } . side - column { display : grid ; grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) } } @ media ( max - width : 640 px ) { . page - hero { padding : 24 px ; align - items : flex - start ; flex - direction : column ; gap : 18 px } . summary - grid , . side - column , . info - grid , . result - grid { grid - template - columns : 1 fr } . inline - form , . form - actions { flex - direction : column } . form - actions . el - button { width : 100 % } . part - row { flex - wrap : wrap } }
. operator - panel > div : first - of - type { align - items : center ; gap : 16 px ; }
. operator - panel > div : first - of - type > span { flex : 0 0 72 px ; white - space : nowrap ; }
. operator - panel > div : first - of - type : deep ( . el - input ) { flex : 1 ; min - width : 0 ; }
. operator - panel > div : first - of - type : deep ( . el - input _ _wrapper ) { min - height : 40 px ; padding : 0 13 px ; border - radius : 9 px ; box - shadow : 0 0 0 1 px # d8e2ef inset ; }
. operator - panel > div : first - of - type : deep ( . el - input _ _inner ) { font - size : 15 px ; font - weight : 600 ; }
. operator - panel > div : not ( : first - of - type ) { min - height : 44 px ; align - items : center ; }
. responsibility - grid . el - checkbox _ _label { gap : 10 px ; line - height : 1.25 ; }
. responsibility - grid . el - checkbox _ _label > span { display : block ; overflow : hidden ; text - overflow : ellipsis ; white - space : nowrap ; }
. responsibility - grid small { line - height : 1.35 ; }
. material - search { display : flex ; gap : 12 px ; margin - bottom : 10 px ; }
. material - search . el - input { flex : 1 ; min - width : 0 ; }
. material - search . el - select { width : 170 px ; flex : none ; }
. material - hint { margin - bottom : 12 px ; color : # 8 a94a6 ; font - size : 13 px ; }
. material - table { width : 100 % ; }
. material - pagination { display : flex ; justify - content : flex - end ; margin - top : 16 px ; }
< / style >