@@ -31,30 +31,15 @@ const emit = defineEmits<{
const editLoading = ref ( false )
const editDetailLoading = ref ( false )
const detailSyncing = ref ( false )
/** 正在同步详情的成员行 id */
const detailSyncing = ref < string > ( '' )
const editGood = ref < Good | GoodDetail | null > ( null )
const editForm = ref ( {
id : '' , goodName : '' , goodImage : '' , countryId : '' , cascaderCategory : [ ] as string [ ] ,
categoryId : '' , positionId : '' ,
} )
const editOriginDetail = computed ( ( ) => ( editGood . value as GoodDetail | null ) ? . originDetail ? ? null )
const editVariants = computed ( ( ) => ( editGood . value as GoodDetail | null ) ? . variants ? ? [ ] )
const editSizeColumns = computed ( ( ) => editOriginDetail . value ? . sizeChart ? . columns ? ? [ ] )
const editSizeRows = computed ( ( ) => {
const rows = editOriginDetail . value ? . sizeChart ? . rows ? ? [ ]
return rows . map ( ( row : any ) => ( {
... row ,
... ( row . measurements ? ? [ ] ) . reduce ( ( out : Record < string , string > , item : any ) => {
out [ item . key ] = item . cm ? ? '-'
return out
} , { } ) ,
} ) )
} )
const editPackageRows = computed ( ( ) => editOriginDetail . value ? . packageSpecs ? . rows ? ? [ ] )
const editIsCustom = computed ( ( ) => editGood . value ? . originGood ? . isCustom === true )
/** 商品自身链接的定价维度(SKU 表列) */
const editLinkDims = computed ( ( ) => linkDims ( editGood . value ? . originGood ? . goodName ? ? null ) )
const categoryCascader = computed ( ( ) => buildCascader ( props . categories ) )
// ─── 自定义商品内容编辑 ───
@@ -176,10 +161,70 @@ function toggleMemberExpand(key: string) {
else {
next . add ( key )
loadMemberPrices ( key )
ensureMemberDetail ( key )
}
expandedMemberKeys . value = next
}
// ─── 成员详情(懒加载:GET /origin-goods/:id) ───
const memberDetailCache = ref < Record < string , any > > ( { } )
function memberDetail ( id : string ) {
return memberDetailCache . value [ id ]
}
async function ensureMemberDetail ( ogId : string ) {
const row = editFamilyMembers . value . find ( ( m ) => m . id === ogId )
if ( ! row || row . source !== 'SDS' || memberDetailCache . value [ ogId ] !== undefined ) return
memberDetailCache . value [ ogId ] = { loading : true }
try {
memberDetailCache . value [ ogId ] = await originGoodsApi . getOriginGood ( ogId )
} catch {
memberDetailCache . value [ ogId ] = null
}
}
function memberSizeColumns ( id : string ) {
return memberDetail ( id ) ? . detail ? . sizeChart ? . columns ? ? [ ]
}
function memberSizeRows ( id : string ) {
const rows = memberDetail ( id ) ? . detail ? . sizeChart ? . rows ? ? [ ]
return rows . map ( ( row : any ) => ( {
... row ,
... ( row . measurements ? ? [ ] ) . reduce ( ( out : Record < string , string > , item : any ) => {
out [ item . key ] = item . cm ? ? '-'
return out
} , { } ) ,
} ) )
}
function memberPackageRows ( id : string ) {
return memberDetail ( id ) ? . detail ? . packageSpecs ? . rows ? ? [ ]
}
function memberVariants ( id : string ) {
return memberDetail ( id ) ? . variants ? ? [ ]
}
function memberDims ( id : string ) {
const row = editFamilyMembers . value . find ( ( m ) => m . id === id )
return linkDims ( row ? . goodName ? ? null )
}
async function handleSyncMemberDetail ( row : { id : string ; sdsGoodId : string } ) {
if ( ! row . sdsGoodId || detailSyncing . value ) return
detailSyncing . value = row . id
try {
const result = await syncApi . syncOneProductDetail ( row . sdsGoodId )
memberDetailCache . value [ row . id ] = await originGoodsApi . getOriginGood ( row . id )
ElMessage . success ( ` 详情同步完成,共 ${ result . variants } 个 SKU ` )
emit ( 'changed' )
} catch ( error : any ) {
ElMessage . error ( error ? . response ? . data ? . message || '商品详情同步失败' )
} finally { detailSyncing . value = '' }
}
/** 该链接在族价格矩阵中的格子(craft/logistics 即该链接的标签维度) */
function loadMemberPrices ( ogId : string ) {
const row = editFamilyMembers . value . find ( ( m ) => m . id === ogId )
@@ -406,22 +451,6 @@ function onEditCascaderChange(val: any) {
editForm . value . categoryId = path . length ? String ( path [ path . length - 1 ] ) : ''
}
async function handleSyncOneDetail ( ) {
if ( editIsCustom . value ) return
const sdsGoodId = editGood . value ? . originGood ? . sdsGoodId
if ( ! sdsGoodId ) return
detailSyncing . value = true
try {
const result = await syncApi . syncOneProductDetail ( sdsGoodId )
const detail = await goodsApi . getGoodById ( editGood . value ! . id )
applyGood ( detail )
ElMessage . success ( ` 详情同步完成,共 ${ result . variants } 个 SKU ` )
emit ( 'changed' )
} catch ( error : any ) {
ElMessage . error ( error ? . response ? . data ? . message || '商品详情同步失败' )
} finally { detailSyncing . value = false }
}
async function handleEditSubmit ( ) {
let customPayload : any = null
if ( editIsCustom . value ) {
@@ -564,28 +593,21 @@ async function handleDeleteGood() {
< span class = "md-label" > 工艺位置 < / span > < span class = "md-val" > { { row . craftLabel || '-' } } < / span >
< span class = "md-label" > 仓库 < / span > < span class = "md-val" > { { row . warehouseLabel || '-' } } < / span >
< / div >
< div class = "member-tags-edit" >
< span class = "md-label" > 标签 < / span >
< el-select
v-model = "memberTagEdits[row.id]"
multiple filterable size = "small"
placeholder = "选择标签"
style = "flex:1"
>
< el-option-group v-for = "g in tagOptionGroups" :key="g.id" :label="g.label" >
< el -option v-for = "t in g.tags" :key="t.id" :label="t.tagName" :value="t.id" / >
< / el-option-group >
< / el-select >
< el-button size = "small" type = "primary" : loading = "memberTagSaving === row.id" @click ="saveMemberTags(row)" > 保存标签 < / el -button >
< el-button v-if = "row.tagsManual" size="small" :loading="memberTagSaving === row.id" @click="resetMemberTags(row)" > 恢复自动 < / el -button >
< el-button
v-if = "row.id === editGood?.originGoodId"
size = "small"
:icon = "Refresh"
:loading = "detailSyncing"
@click ="handleSyncOneDetail"
> 同步详情 < / el-button >
< / div >
< div class = "member-tags-edit" >
< span class = "md-label" > 标签 < / span >
< el-select
v-model = "memberTagEdits[row.id]"
multiple filterable size = "small"
placeholder = "选择标签"
style = "flex:1"
>
< el-option-group v-for = "g in tagOptionGroups" :key="g.id" :label="g.label" >
< el -option v-for = "t in g.tags" :key="t.id" :label="t.tagName" :value="t.id" / >
< / el-option-group >
< / el-select >
< el-button size = "small" type = "primary" : loading = "memberTagSaving === row.id" @click ="saveMemberTags(row)" > 保存标签 < / el -button >
< el-button v-if = "row.tagsManual" size="small" :loading="memberTagSaving === row.id" @click="resetMemberTags(row)" > 恢复自动 < / el -button >
< / div >
< div v-if = "row.craftLabel && row.logisticsLabel" class="member-price-block" >
< div class = "member-price-head" >
< span class = "md-label" > 尺码 × 颜色 → 价格 < / span >
@@ -612,6 +634,71 @@ async function handleDeleteGood() {
< / el-table-column >
< / el-table >
< / div >
< div v-if = "row.source === 'SDS'" class="member-extra" >
< div v-if = "!memberDetail(row.id) || memberDetail(row.id).loading" class="md-empty" > 详情加载中 … < / div >
< div v-else-if = "!memberDetail(row.id).hasDetail" class="md-empty" >
尚未同步详情
< el -button size = "small" :icon = "Refresh" : loading = "detailSyncing === row.id" @click ="handleSyncMemberDetail(row)" > 同步详情 < / el -button >
< / div >
< el-tabs v-else class = "member-detail-tabs" >
< el-tab-pane label = "商品详情" >
< el-descriptions :column = "2" border size = "small" >
< el-descriptions-item label = "商品编码" > { { memberDetail ( row . id ) . detail . productCode || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "英文名称" > { { memberDetail ( row . id ) . detail . englishName || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "生产周期" > { { memberDetail ( row . id ) . detail . productionCycleHours ? ? '-' } } 小时 < / el-descriptions-item >
< el-descriptions-item label = "净重" > { { memberDetail ( row . id ) . detail . minWeightG ? ? '-' } } g < / el-descriptions-item >
< el-descriptions-item label = "生产工艺" > { { memberDetail ( row . id ) . detail . productionProcess || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "材质" > { { memberDetail ( row . id ) . detail . materialDescription || '-' } } < / el-descriptions-item >
< / el-descriptions >
< / el-tab-pane >
< el-tab-pane : label = "`尺码表 (${memberSizeRows(row.id).length})`" >
< el-table :data = "memberSizeRows(row.id)" border size = "small" max -height = " 240 " >
< el-table-column prop = "sizeName" label = "尺码" width = "100" fixed / >
< el-table-column
v-for = "column in memberSizeColumns(row.id)"
:key = "column.key"
:prop = "column.key"
: label = "`${column.name} (cm)`"
min -width = " 110 "
/ >
< / el-table >
< / el-tab-pane >
< el-tab-pane : label = "`包装规格 (${memberPackageRows(row.id).length})`" >
< el-table :data = "memberPackageRows(row.id)" border size = "small" max -height = " 240 " >
< el-table-column prop = "sizeName" label = "尺码" width = "90" fixed / >
< el-table-column label = "包装尺寸 (cm)" min -width = " 150 " >
< template # default = "{ row: pkg }" >
{ { pkg . dimensionsCm ? ` ${ pkg . dimensionsCm . length } × ${ pkg . dimensionsCm . width } × ${ pkg . dimensionsCm . height } ` : '-' } }
< / template >
< / el-table-column >
< el-table-column prop = "volumeCm3" label = "体积 (cm³)" width = "110" / >
< el-table-column prop = "grossWeightG" label = "含包装重量 (g)" width = "140" / >
< / el-table >
< / el-tab-pane >
< el-tab-pane : label = "`SKU (${memberVariants(row.id).length})`" >
< el-table :data = "memberVariants(row.id)" border size = "small" max -height = " 240 " >
< el-table-column prop = "sku" label = "SKU" min -width = " 160 " fixed / >
< el-table-column label = "物流" width = "100" >
< template # default > { { memberDims ( row . id ) . logistics || '-' } } < / template >
< / el-table-column >
< el-table-column label = "工艺" width = "90" >
< template # default > { { memberDims ( row . id ) . crafts . join ( ' / ' ) || '-' } } < / template >
< / el-table-column >
< el-table-column label = "印花数量" width = "95" >
< template # default > { { memberDims ( row . id ) . printCount || '-' } } < / template >
< / el-table-column >
< el-table-column prop = "sizeName" label = "尺码" width = "85" / >
< el-table-column prop = "colorName" label = "颜色" width = "100" / >
< el-table-column prop = "price" label = "价格" width = "90" / >
< el-table-column label = "状态" width = "80" >
< template # default = "{ row: variant }" >
< el-tag : type = "variant.enabled ? 'success' : 'info'" size = "small" > { { variant . enabled ? '可用' : '停用' } } < / el-tag >
< / template >
< / el-table-column >
< / el-table >
< / el-tab-pane >
< / el-tabs >
< / div >
< / div >
< / template >
< div v-if = "!editFamilyLoaded && editFamilyId" class="edit-family-loading" > 族成员加载中 … < / div >
@@ -644,9 +731,10 @@ async function handleDeleteGood() {
< / el-form-item >
< / el-form >
< el-tabs v-if = "editOriginDetail" class="detail-tabs" >
<!-- 自定义商品内容编辑 ( SDS 商品的详情在 「 关联原产品 」 成员面板内查看 ) -- >
< el-tabs v-if = "editIsCustom" class="detail-tabs" >
< el -tab -pane label = "商品详情" >
< el-form v-if = "editIsCustom" label-width="100px" class= "custom-detail-form">
< el-form label -width = " 100px " class = "custom-detail-form" >
< el-form-item label = "商品编码" > < el-input v-model = "customContentForm.productCode" / > < / el-form-item >
< el-form-item label = "英文名称" > < el-input v-model = "customContentForm.englishName" / > < / el-form-item >
< el-form-item label = "生产周期" > < el-input-number v-model = "customContentForm.productionCycleHours" :min="0" /><span style="margin-left:8px" > 小时 < / span > < / el -form -item >
@@ -667,86 +755,35 @@ async function handleDeleteGood() {
< el-form-item label = "商品选项 JSON" > < el-input v-model = "customContentForm.optionsJson" type="textarea" :rows="6" / > < / el-form-item >
< el-form-item label = "媒体数据 JSON" > < el-input v-model = "customContentForm.mediaJson" type="textarea" :rows="6" / > < / el-form-item >
< / el-form >
< el-descriptions v-else :column = "2" border size = "small" >
< el-descriptions-item label = "商品编码" > { { editOriginDetail . productCode || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "英文名称" > { { editOriginDetail . englishName || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "生产周期" > { { editOriginDetail . productionCycleHours ? ? '-' } } 小时 < / el-descriptions-item >
< el-descriptions-item label = "净重" > { { editOriginDetail . minWeightG ? ? '-' } } g < / el-descriptions-item >
< el-descriptions-item label = "生产工艺" > { { editOriginDetail . productionProcess || '-' } } < / el-descriptions-item >
< el-descriptions-item label = "材质" > { { editOriginDetail . materialDescription || '-' } } < / el-descriptions-item >
< / el-descriptions >
< / el-tab-pane >
< el-tab-pane : label = "` 尺码表 (${editSizeRows.length})` " >
< el-input v-if = "editIsCustom" v-model=" customContentForm.sizeChartJson" type="textarea" :rows="14" placeholder="尺码表 JSON" / >
< el-table v-else :data = "editSizeRows" border max -height = " 320 " >
< el-table-column prop = "sizeName" label = "尺码" width = "100" fixed / >
< el-table-column
v-for = "column in editSizeColumns"
:key = "column.key"
:prop = "column.key"
: label = "`${column.name} (cm)`"
min -width = " 120 "
/ >
< / el-table >
< el-tab-pane label = "尺码表" >
< el-input v-model = "customContentForm.sizeChartJson" type="textarea" :rows="14" placeholder="尺码表 JSON" / >
< / el-tab-pane >
< el-tab-pane : label = "` 包装规格 (${editPackageRows.length})` " >
< el-input v-if = "editIsCustom" v-model=" customContentForm.packageSpecsJson" type="textarea" :rows="14" placeholder="包装规格 JSON" / >
< el-table v-else :data = "editPackageRows" border max -height = " 320 " >
< el-table-column prop = "sizeName" label = "尺码" width = "90" fixed / >
< el-table-column label = "包装尺寸 (cm)" min -width = " 160 " >
< template # default = "{ row }" >
{ { row . dimensionsCm ? ` ${ row . dimensionsCm . length } × ${ row . dimensionsCm . width } × ${ row . dimensionsCm . height } ` : '-' } }
< / template >
< / el-table-column >
< el-table-column prop = "volumeCm3" label = "体积 (cm³)" width = "120" / >
< el-table-column prop = "grossWeightG" label = "含包装重量 (g)" width = "150" / >
< / el-table >
< el-tab-pane label = "包装规格" >
< el-input v-model = "customContentForm.packageSpecsJson" type="textarea" :rows="14" placeholder="包装规格 JSON" / >
< / el-tab-pane >
< el-tab-pane : label = "`SKU (${editV ariants.length})`" >
< template v-if = "editIsCustom" >
< div style = "display:flex;justify-content:flex-end;margin-bottom:8px" > < el-button size = "small" :icon = "Plus" @click ="addCustomV ariant"> 添加 SKU < / el -button > < / div >
< el-table :data = "customContentForm.variants" border max -height = " 320 " >
< el-table-column label = "SKU" min -width = " 160 " > < template # default = "{ row }" > < el-input v-model = "row.sku " / > < / template > < / el-table-column >
< el-table-column label = "尺码 ID " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.sizeId " / > < / template > < / el-table-column >
< el-table-column label = "尺码 " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.sizeName " / > < / template > < / el-table-column >
< el-table-column label = "颜色 ID " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.colorId " / > < / template > < / el-table-column >
< el-table-column label = "颜 色" width = "120" > < template # default = "{ row }" > < el-input v-model = "row.colorName " / > < / template > < / el-table-column >
< el-table-column label = "色值 " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.colorHex" placeholder="#FFFFFF " / > < / template > < / el-table-column >
< el-table-column label = "图片 " min -width = " 180 " > < template # default = "{ row }" > < el-input v-model = "row.imageUrl " / > < / template > < / el-table-column >
< el-table-column label = "价格 " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.p rice" / > < / template > < / el-table-column >
< el-table-column label = "原价 " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.originalPrice " / > < / template > < / el-table-column >
< el-table-column label = "重量(g )" width = "12 0" > < template # default = "{ row }" > < el-input v-model = "row.weightG " / > < / template > < / el-table-column >
< el-table-column label = "包装长 (cm)" width = "130" > < template # default = "{ row }" > < el-input v-model = "row.boxLeng thCm" / > < / template > < / el-table-column >
< el-table-column label = "包装宽 (cm)" width = "130" > < template # default = "{ row }" > < el-input v-model = "row.boxWidth Cm" / > < / template > < / el-table-column >
< el-table-column label = "包装高(cm)" width = "130" > < template # default = "{ row }" > < el-input v-model = "row.boxHeightCm " / > < / template > < / el-table-column >
< el-table-column label = "设计数据 JSON" min -width = " 220 " > < template # default = "{ row }" > < el-input v-model = "row.designDataJson" type="textarea" :rows="2 " / > < / template > < / el-table-column >
< el-table-column label = "启用 " width = "8 0" > < template # default = "{ row }" > < el-switch v-model = "row.enabled" / > < / template > < / el-table-column >
< el-table-column label = "操作" width = "70" > < template # default = "{ $index }" > < el-button link type = "danger" @click ="customContentForm.variants.splice($index, 1)" > 删除 < / el -button > < / template > < / el-table-column >
< / el-table >
< / template >
< el-table v-else :data = "editVariants" border max -height = " 320 " >
< el-table-column prop = "sku" label = "SKU" min -width = " 170 " fixed / >
< el-table-column label = "物流" width = "110" >
< template # default > { { editLinkDims . logistics || '-' } } < / template >
< / el-table-column >
< el-table-column label = "工艺" width = "100" >
< template # default > { { editLinkDims . crafts . join ( ' / ' ) || '-' } } < / template >
< / el-table-column >
< el-table-column label = "印花数量" width = "100" >
< template # default > { { editLinkDims . printCount || '-' } } < / template >
< / el-table-column >
< el-table-column prop = "sizeName" label = "尺码" width = "90" / >
< el-table-column prop = "colorName" label = "颜色" width = "100" / >
< el-table-column prop = "price" label = "价格" width = "100" / >
< el-table-column label = "状态" width = "90" >
< template # default = "{ row }" >
< el-tag : type = "row.enabled ? 'success' : 'info'" size = "small" > { { row . enabled ? '可用' : '停用' } } < / el-tag >
< / template >
< / el-table-column >
< el-tab-pane : label = "`SKU (${customContentForm.v ariants.length})`" >
< div style = "display:flex;justify-content:flex-end;margin-bottom:8px" > < el-button size = "small" :icon = "Plus" @click ="addCustomVariant" > 添加 SKU < / el -button > < / div >
< el-table :data = "customContentForm.v ariants " border max -height = " 320 " >
< el-table-column label = "SKU" min -width = " 160 " > < template # default = "{ row }" > < el-input v-model = "row.sku" / > < / template > < / el-table-column >
< el-table-column label = "尺码 ID" width = "120" > < template # default = "{ row }" > < el-input v-model = "row.sizeId " / > < / template > < / el-table-column >
< el-table-column label = "尺码" width = "120" > < template # default = "{ row }" > < el-input v-model = "row.sizeName " / > < / template > < / el-table-column >
< el-table-column label = "颜色 ID " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.colorId " / > < / template > < / el-table-column >
< el-table-column label = "颜色" width = "120" > < template # default = "{ row }" > < el-input v-model = "row.colorName " / > < / template > < / el-table-column >
< el-table-column label = "色值 " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.colorHex" placeholder="#FFFFFF " / > < / template > < / el-table-column >
< el-table-column label = "图片 " min -width = " 180 " > < template # default = "{ row }" > < el-input v-model = "row.imageUrl " / > < / template > < / el-table-column >
< el-table-column label = "价格 " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.price " / > < / template > < / el-table-column >
< el-table-column label = "原 价" width = "120" > < template # default = "{ row }" > < el-input v-model = "row.originalP rice" / > < / template > < / el-table-column >
< el-table-column label = "重量(g) " width = "120" > < template # default = "{ row }" > < el-input v-model = "row.weightG " / > < / template > < / el-table-column >
< el-table-column label = "包装长(cm )" width = "13 0" > < template # default = "{ row }" > < el-input v-model = "row.boxLengthCm " / > < / template > < / el-table-column >
< el-table-column label = "包装宽 (cm)" width = "130" > < template # default = "{ row }" > < el-input v-model = "row.boxWid thCm" / > < / template > < / el-table-column >
< el-table-column label = "包装高 (cm)" width = "130" > < template # default = "{ row }" > < el-input v-model = "row.boxHeight Cm" / > < / template > < / el-table-column >
< el-table-column label = "设计数据 JSON" min -width = " 220 " > < template # default = "{ row }" > < el-input v-model = "row.designDataJson" type="textarea" :rows="2 " / > < / template > < / el-table-column >
< el-table-column label = "启用" width = "80" > < template # default = "{ row }" > < el-switch v-model = "row.enabled " / > < / template > < / el-table-column >
< el-table-column label = "操作 " width = "7 0" > < template # default = "{ $index }" > < el-button link type = "danger" @click ="customContentForm.variants.splice($index, 1)" > 删除 < / el -button > < / template > < / el-table-column >
< / el-table >
< / el-tab-pane >
< / el-tabs >
< el-empty v-else-if = "!editDetailLoading" description="尚未同步商品详情" :image-size="60" / >
< template # footer >
< el-button type = "danger" @click ="handleDeleteGood" > 删除 < / el -button >
< el-button @click ="emit('update:visible', false)" > 取消 < / el -button >
@@ -800,6 +837,12 @@ async function handleDeleteGood() {
. member - tags - edit . md - label { flex - shrink : 0 ; }
. member - price - block { border - top : 1 px dashed # e4e7ed ; padding - top : 8 px ; }
. member - price - head { display : flex ; align - items : center ; justify - content : space - between ; margin - bottom : 6 px ; }
. member - extra { border - top : 1 px dashed # e4e7ed ; padding - top : 8 px ; }
. md - empty {
display : flex ; align - items : center ; justify - content : space - between ; gap : 8 px ;
font - size : 12 px ; color : var ( -- el - text - color - placeholder ) ; padding : 4 px 0 ;
}
. member - detail - tabs : deep ( . el - tabs _ _header ) { margin - bottom : 8 px ; }
. edit - family - loading { color : var ( -- el - text - color - placeholder ) ; font - size : 12 px ; padding : 4 px 0 ; }
. detail - tabs { margin - top : 12 px ; padding - top : 4 px ; border - top : 1 px solid # ebeef5 ; }
. select - inline { display : flex ; align - items : center ; gap : 6 px ; width : 100 % ; }