From aeff7b0782847a1fda77f96624b97b53e2f99e1a Mon Sep 17 00:00:00 2001 From: 田源 <lastanimals@163.com> Date: 星期二, 17 十二月 2024 10:42:23 +0800 Subject: [PATCH] 对象建模模块按钮权限 --- Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue | 207 ++++++++++++++++++++++++++++++++------------------- 1 files changed, 130 insertions(+), 77 deletions(-) diff --git a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue index 2ab9bd1..9d3f689 100644 --- a/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue +++ b/Source/plt-web/plt-web-ui/src/views/modelingMenu/modeling/attributePool/index.vue @@ -18,20 +18,33 @@ @current-change="currentChange" > <template slot="menuLeft" slot-scope="scope"> - <el-button icon="el-icon-plus" plain size="small" type="primary" @click="rowSaveHandlerClick">鍒涘缓</el-button> - <el-button icon="el-icon-delete" plain size="small" type="danger" @click="allDelHandler">鍒犻櫎</el-button> - <el-button icon="el-icon-view" plain size="small" type="primary" @click="chekView">鏌ョ湅浣跨敤鑼冨洿</el-button> - <el-button icon="el-icon-download" plain size="small" type="primary" @click="downloadTemplateHandler"> + <el-button v-if="permissionList.addBtn" icon="el-icon-plus" plain size="small" type="primary" + @click="rowSaveHandlerClick">鍒涘缓 + </el-button> + <el-button v-if="permissionList.delBtn" icon="el-icon-delete" plain size="small" type="danger" + @click="allDelHandler">鍒犻櫎 + </el-button> + <el-button v-if="permissionList.viewTheScopeBtn" icon="el-icon-view" plain size="small" type="primary" + @click="chekView">鏌ョ湅浣跨敤鑼冨洿 + </el-button> + <el-button v-if="permissionList.downloadImportTemplateBtn" icon="el-icon-download" plain size="small" + type="primary" @click="downloadTemplateHandler"> 涓嬭浇瀵煎叆妯℃澘 </el-button> - <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="upLoadHandler">瀵煎叆</el-button> - <el-button icon="el-icon-download" plain size="small" type="primary" @click="downLoadHandler">瀵煎嚭</el-button> + <el-button v-if="permissionList.importBtn" icon="el-icon-upload2" plain size="small" type="primary" + @click="upLoadHandler">瀵煎叆 + </el-button> + <el-button v-if="permissionList.exportBtn" icon="el-icon-download" plain size="small" type="primary" + @click="downLoadHandler">瀵煎嚭 + </el-button> </template> <template slot="menu" slot-scope="scope"> - <el-button icon="el-icon-edit" size="small" type="text" @click="editBtnClick(scope.row)">缂栬緫 + <el-button v-if="permissionList.editBtn" icon="el-icon-edit" size="small" type="text" + @click="editBtnClick(scope.row)">缂栬緫 </el-button> - <el-button icon="el-icon-delete" size="small" type="text" @click="rowDeleteHandler(scope.row)">鍒犻櫎 + <el-button v-if="permissionList.delBtn" icon="el-icon-delete" size="small" type="text" + @click="rowDeleteHandler(scope.row)">鍒犻櫎 </el-button> </template> </avue-crud> @@ -41,7 +54,7 @@ <el-aside width="30%"> <basic-container> <div style="height: 85vh; overflow-y: auto"> - <el-descriptions :column="1" border size="medium" title="灞炴�ч」" :labelStyle="{width:'120px'}"> + <el-descriptions :column="1" :labelStyle="{width:'120px'}" border size="medium" title="灞炴�ч」"> <el-descriptions-item> <template slot="label"> 鍚嶇О @@ -55,7 +68,7 @@ 鏍囩 </template> <div> - {{ lastItem.name }} + {{ lastItem.name }} </div> </el-descriptions-item> <el-descriptions-item> @@ -63,7 +76,7 @@ 鎻忚堪 </template> <div> - {{ lastItem.description }} + {{ lastItem.description }} </div> </el-descriptions-item> <el-descriptions-item> @@ -75,17 +88,18 @@ </el-descriptions> <!-- 鍊煎煙 --> - <el-descriptions v-if="!isSpecialDataType" :column="1" :title="lastItem.attributeDataType || 'VTString'" border - class="margin-top" - size="medium" :labelStyle="{width:'120px'}"> + <el-descriptions v-if="!isSpecialDataType" :column="1" :labelStyle="{width:'120px'}" + :title="lastItem.attributeDataType || 'VTString'" + border + class="margin-top" size="medium"> <el-descriptions-item> <template slot="label"> 鍏佽涓虹┖ </template> <div> - <el-tag :type="lastItem.nullableFlag ? 'success' : 'danger'"> - {{ lastItem.nullableFlag ? '鏄�' : '鍚�' }} - </el-tag> + <el-tag :type="lastItem.nullableFlag ? 'success' : 'danger'"> + {{ lastItem.nullableFlag ? '鏄�' : '鍚�' }} + </el-tag> </div> </el-descriptions-item> <el-descriptions-item v-if="accuracy"> @@ -99,7 +113,7 @@ 闀垮害 </template> <div> - {{ lastItem.attrLength }} + {{ lastItem.attrLength }} </div> </el-descriptions-item> <el-descriptions-item> @@ -107,20 +121,20 @@ 榛樿鍊� </template> <div> - {{ lastItem.defaultValue }} + {{ lastItem.defaultValue }} </div> </el-descriptions-item> </el-descriptions> <!-- VTString --> <el-descriptions v-if="lastItem.attributeDataType === 'VTString' || !lastItem.attributeDataType" - :column="1" border class="margin-top" size="medium" title="鍊煎煙" :labelStyle="{width:'120px'}"> + :column="1" :labelStyle="{width:'120px'}" border class="margin-top" size="medium" title="鍊煎煙"> <el-descriptions-item> <template slot="label"> 褰撳墠绫诲瀷 </template> <div> - {{ lastItem.version ? '閾炬帴绫诲瀷' : '涓氬姟绫诲瀷' }} + {{ lastItem.version ? '閾炬帴绫诲瀷' : '涓氬姟绫诲瀷' }} </div> </el-descriptions-item> <el-descriptions-item> @@ -128,7 +142,7 @@ 褰撳墠绫诲瀷鍊� </template> <div> - {{ lastItem.version ? lastItem.linkTypeName : lastItem.btmTypeId }} + {{ lastItem.version ? lastItem.linkTypeName : lastItem.btmTypeId }} </div> </el-descriptions-item> <el-descriptions-item v-if="lastItem.version"> @@ -136,7 +150,7 @@ 褰撳墠鐗堟湰娆� </template> <div> - {{ lastItem.version }} + {{ lastItem.version }} </div> </el-descriptions-item> <el-descriptions-item> @@ -144,9 +158,9 @@ 浣跨敤鏋氫妇 </template> <div> - <el-tag :type="lastItem.enumId ? 'success' : 'danger'"> - {{ lastItem.enumId ? '鏄�' : '鍚�' }} - </el-tag> + <el-tag :type="lastItem.enumId ? 'success' : 'danger'"> + {{ lastItem.enumId ? '鏄�' : '鍚�' }} + </el-tag> </div> </el-descriptions-item> <el-descriptions-item> @@ -154,7 +168,7 @@ 褰撳墠鏋氫妇绫诲瀷 </template> <div> - {{ lastItem.enumId }} + {{ lastItem.enumId }} </div> </el-descriptions-item> <el-descriptions-item> @@ -169,15 +183,15 @@ <!-- VTInteger && VTInteger --> <el-descriptions v-if="lastItem.attributeDataType === 'VTInteger' || lastItem.attributeDataType === 'VTInteger'" - :column="1" border class="margin-top" size="medium" title="鍊煎煙" :labelStyle="{width:'120px'}"> + :column="1" :labelStyle="{width:'120px'}" border class="margin-top" size="medium" title="鍊煎煙"> <el-descriptions-item> <template slot="label"> 浣跨敤鏋氫妇 </template> <div> - <el-tag :type="lastItem.enumFlag ? 'success' : 'danger'"> - {{ lastItem.enumFlag ? '鏄�' : '鍚�' }} - </el-tag> + <el-tag :type="lastItem.enumFlag ? 'success' : 'danger'"> + {{ lastItem.enumFlag ? '鏄�' : '鍚�' }} + </el-tag> </div> </el-descriptions-item> <el-descriptions-item> @@ -185,7 +199,7 @@ 鏋氫妇绫诲瀷 </template> <div> - {{ lastItem.enumFlag }} + {{ lastItem.enumFlag }} </div> </el-descriptions-item> <el-descriptions-item> @@ -200,7 +214,7 @@ </el-descriptions> <!-- VTDouble --> <el-descriptions v-if="lastItem.attributeDataType === 'VTDouble'" - :column="1" border class="margin-top" size="medium" title="鍊煎煙" :labelStyle="{width:'120px'}"> + :column="1" :labelStyle="{width:'120px'}" border class="margin-top" size="medium" title="鍊煎煙"> <el-descriptions-item> <template slot="label"> @@ -254,20 +268,22 @@ </el-col> <!-- VTString --> <div v-if="form.attributeDataType === 'VTString'" style="clear: both"> - <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px">{{ form.attributeDataType }}</h3> + <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px">{{ + form.attributeDataType + }}</h3> <el-col :span="8"> <el-form-item label="闀垮害锛�" prop="attrLength"> - <el-input-number v-model="form.attrLength" controls-position="right" :min="0"></el-input-number> + <el-input-number v-model="form.attrLength" :min="0" controls-position="right"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> - <el-form-item v-if="form.enumSwitch" label="榛樿鍊硷細" prop="defaultValue"> + <el-form-item v-if="form.enumSwitch" label="榛樿鍊硷細" prop="defaultValue"> <el-select v-model="form.defaultValue"> <el-option v-for="(item,index) in enumAddListChange" :key="index" :label="item.replace('=','')" :value="item.replace('=','')"></el-option> </el-select> </el-form-item> - <el-form-item v-else label="榛樿鍊硷細" prop="defaultValue"> + <el-form-item v-else label="榛樿鍊硷細" prop="defaultValue"> <el-input v-model="form.defaultValue"></el-input> </el-form-item> </el-col> @@ -288,7 +304,7 @@ </el-col> <el-col :span="8"> <el-form-item label="閫夋嫨鍙傜収绫诲瀷锛�" prop="referValue"> - <el-input v-model="form.referValue" @focus="referFormFocusHandler" :clearable="true"></el-input> + <el-input v-model="form.referValue" :clearable="true" @focus="referFormFocusHandler"></el-input> </el-form-item> </el-col> <el-col :span="8"> @@ -307,7 +323,8 @@ </el-col> <el-col :span="8"> <el-form-item :label="form.enumSwitch ? '鏋氫妇閫夋嫨锛�' : '娣诲姞鍊煎煙锛�'" prop="enumSwitch"> - <el-select v-if="form.enumSwitch" v-model="form.enumId" placeholder="璇烽�夋嫨鏋氫妇绫诲瀷" @change="enumSelectChange"> + <el-select v-if="form.enumSwitch" v-model="form.enumId" placeholder="璇烽�夋嫨鏋氫妇绫诲瀷" + @change="enumSelectChange"> <el-option v-for="(item,index) in attributeDataTypePickList" :key="index" :label="item.key" :value="item.key"></el-option> </el-select> @@ -317,29 +334,36 @@ <el-col :span="8"> <el-form-item v-if="!form.enumSwitch" label-width="10px" labeldd="杩愮畻绗︼細"> <div> - <el-button size="mini" @click="enumAddHandler"> = </el-button> + <el-button size="mini" @click="enumAddHandler"> =</el-button> </div> </el-form-item> </el-col> - <el-col :span="24" v-if="form.rangeValue && form.rangeValue.length>0"> + <el-col v-if="form.rangeValue && form.rangeValue.length>0" :span="24"> <el-form-item :label="form.enumSwitch ? '褰撳墠鏋氫妇鍊硷細' : '褰撳墠鍊煎煙锛�'" prop="rangeValue"> - <el-tag :key="item" v-for="item in form.rangeValue.split('\n')" plain :closable="!form.enumSwitch" type="success" @close="handleRangeValueDel(item)" style="margin: 0 10px 5px 0">{{ item }}</el-tag> - <el-input v-model="form.rangeValue" :readonly="form.enumSwitch" type="textarea" :rows="2" style="width: 0;height:0;overflow: hidden"></el-input> + <el-tag v-for="item in form.rangeValue.split('\n')" :key="item" :closable="!form.enumSwitch" plain + style="margin: 0 10px 5px 0" type="success" @close="handleRangeValueDel(item)">{{ item }} + </el-tag> + <el-input v-model="form.rangeValue" :readonly="form.enumSwitch" :rows="2" + style="width: 0;height:0;overflow: hidden" + type="textarea"></el-input> </el-form-item> </el-col> </div> </div> <!-- VTInteger VTLong --> - <div v-else-if="form.attributeDataType === 'VTInteger' || form.attributeDataType === 'VTLong' " style="clear: both"> - <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px">{{ form.attributeDataType }}</h3> + <div v-else-if="form.attributeDataType === 'VTInteger' || form.attributeDataType === 'VTLong' " + style="clear: both"> + <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px">{{ + form.attributeDataType + }}</h3> <el-col :span="8"> - <el-form-item v-if="form.enumSwitch" label="榛樿鍊硷細" prop="defaultValue"> + <el-form-item v-if="form.enumSwitch" label="榛樿鍊硷細" prop="defaultValue"> <el-select v-model="form.defaultValue"> <el-option v-for="(item,index) in enumAddListChange" :key="index" :label="item.replace('=','')" :value="item.replace('=','')"></el-option> </el-select> </el-form-item> - <el-form-item v-else label="榛樿鍊硷細" prop="defaultValue"> + <el-form-item v-else label="榛樿鍊硷細" prop="defaultValue"> <el-input-number v-model="form.defaultValue" controls-position="right"></el-input-number> </el-form-item> </el-col> @@ -378,35 +402,44 @@ </div> </el-form-item> </el-col> - <el-col :span="24" v-if="form.rangeValue && form.rangeValue.length>0"> + <el-col v-if="form.rangeValue && form.rangeValue.length>0" :span="24"> <el-form-item :label="form.enumSwitch ? '褰撳墠鏋氫妇鍊硷細' : '褰撳墠鍊煎煙锛�'" prop="rangeValue"> - <el-tag :key="item" v-for="item in form.rangeValue.split('\n')" plain :closable="!form.enumSwitch" type="success" @close="handleRangeValueDel(item)" style="margin: 0 10px 5px 0">{{ item }}</el-tag> - <el-input v-model="form.rangeValue" :readonly="form.enumSwitch" type="textarea" :rows="2" style="width: 0;height:0;overflow: hidden"></el-input> + <el-tag v-for="item in form.rangeValue.split('\n')" :key="item" :closable="!form.enumSwitch" plain + style="margin: 0 10px 5px 0" type="success" @close="handleRangeValueDel(item)">{{ item }} + </el-tag> + <el-input v-model="form.rangeValue" :readonly="form.enumSwitch" :rows="2" + style="width: 0;height:0;overflow: hidden" + type="textarea"></el-input> </el-form-item> </el-col> </div> <!-- VTDouble --> <div v-else-if="form.attributeDataType === 'VTDouble'" style="clear: both"> - <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px">{{ form.attributeDataType }}</h3> + <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px">{{ + form.attributeDataType + }}</h3> <el-col :span="8"> <el-form-item label="绮惧害锛�" prop="precisionLength"> - <el-input-number v-model="form.precisionLength" controls-position="right" :precision="0" :step="1" :min="0"></el-input-number> + <el-input-number v-model="form.precisionLength" :min="0" :precision="0" :step="1" + controls-position="right"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="闀垮害锛�" prop="scaleLength"> - <el-input-number v-model="form.scaleLength" controls-position="right" :precision="0" :step="1" :min="0"></el-input-number> + <el-input-number v-model="form.scaleLength" :min="0" :precision="0" :step="1" + controls-position="right"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> - <el-form-item v-if="form.enumSwitch" label="榛樿鍊硷細" prop="defaultValue"> + <el-form-item v-if="form.enumSwitch" label="榛樿鍊硷細" prop="defaultValue"> <el-select v-model="form.defaultValue"> <el-option v-for="(item,index) in enumAddListChange" :key="index" :label="item.replace('=','')" :value="item.replace('=','')"></el-option> </el-select> </el-form-item> - <el-form-item v-else label="榛樿鍊硷細" prop="defaultValue"> - <el-input-number v-model="form.defaultValue" controls-position="right" :precision="form.precisionLength"></el-input-number> + <el-form-item v-else label="榛樿鍊硷細" prop="defaultValue"> + <el-input-number v-model="form.defaultValue" :precision="form.precisionLength" + controls-position="right"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> @@ -417,7 +450,7 @@ <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px;clear: both">鍊煎煙</h3> <el-col :span="8"> <el-form-item :label="form.enumSwitch ? '鏋氫妇閫夋嫨锛�' : '娣诲姞鍊煎煙锛�'" prop="enumAddValue"> - <el-input v-model="form.enumAddValue"> </el-input> + <el-input v-model="form.enumAddValue"></el-input> </el-form-item> </el-col> <el-col :span="16"> @@ -433,15 +466,21 @@ </div> </el-form-item> </el-col> - <el-col :span="24" v-if="form.rangeValue && form.rangeValue.length>0"> + <el-col v-if="form.rangeValue && form.rangeValue.length>0" :span="24"> <el-form-item :label="form.enumSwitch ? '褰撳墠鏋氫妇鍊硷細' : '褰撳墠鍊煎煙锛�'" prop="rangeValue"> - <el-tag :key="item" v-for="item in form.rangeValue.split('\n')" plain closable type="success" @close="handleRangeValueDel(item)" style="margin: 0 10px 5px 0">{{ item }}</el-tag> - <el-input v-model="form.rangeValue" type="textarea" :rows="2" style="width: 0;height:0;overflow: hidden"></el-input> + <el-tag v-for="item in form.rangeValue.split('\n')" :key="item" closable plain + style="margin: 0 10px 5px 0" + type="success" @close="handleRangeValueDel(item)">{{ item }} + </el-tag> + <el-input v-model="form.rangeValue" :rows="2" style="width: 0;height:0;overflow: hidden" + type="textarea"></el-input> </el-form-item> </el-col> </div> <div v-else-if="form.attributeDataType === 'VTBoolean'" style="clear: both"> - <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px">{{ form.attributeDataType }}</h3> + <h3 style="border-bottom: 1px solid #eee;margin: -10px 0 20px;line-height: 40px">{{ + form.attributeDataType + }}</h3> <el-col :span="8"> <el-form-item label="榛樿鍊硷細" prop="defaultValue"> <el-select v-model="form.defaultValue"> @@ -557,6 +596,7 @@ import basicOption from '@/util/basic-option'; import {column} from "./option" import func from "@/util/func"; +import {mapGetters} from "vuex"; export default { name: "index", @@ -667,7 +707,7 @@ searchMenuSpan: 8, refreshBtn: false, selection: false, - header:false, + header: false, column: [ { label: '鍚嶇О', @@ -695,8 +735,8 @@ description: "", nullableFlag: true, attrLength: 50, - precisionLength:2,//绮惧害 - scaleLength:20,//闀垮害 + precisionLength: 2,//绮惧害 + scaleLength: 20,//闀垮害 enumFlag: false, enumId: "", enumSwitch: false, @@ -725,6 +765,18 @@ } }, computed: { + ...mapGetters(["permission"]), + permissionList() { + return { + addBtn: this.vaildData(this.permission[this.$route.query.id].ADD, false), + delBtn: this.vaildData(this.permission[this.$route.query.id].DELETE, false), + editBtn: this.vaildData(this.permission[this.$route.query.id].EDIT, false), + exportBtn: this.vaildData(this.permission[this.$route.query.id].EXPORT, false), + importBtn: this.vaildData(this.permission[this.$route.query.id].IMPORT, false), + downloadImportTemplateBtn: this.vaildData(this.permission[this.$route.query.id].downloadImportTemplate, false), + viewTheScopeBtn: this.vaildData(this.permission[this.$route.query.id].viewTheScope, false), + }; + }, lastItem() { return this.selectList.length > 0 ? this.selectList[this.selectList.length - 1] : {}; }, @@ -950,18 +1002,18 @@ } this.getEnumMapByTypeHandler(this.form.attributeDataType); this.addVisible = true; - this.lastIndex=-1;//闃叉瑙﹀彂琛岀偣鍑讳簨浠跺悗娓呴櫎閫変腑椤� + this.lastIndex = -1;//闃叉瑙﹀彂琛岀偣鍑讳簨浠跺悗娓呴櫎閫変腑椤� }, // 灞炴�х被鍨嬩笅鎷夋change attributeDataTypeChange(val) { this.form.rangeValue = null; - this.form.nullableFlag=true; + this.form.nullableFlag = true; this.getEnumMapByTypeHandler(val); this.form.enumSwitch = false; if (val === 'VTBoolean') { this.form.defaultValue = 'false'; - } else{ + } else { this.form.defaultValue = ''; } }, @@ -991,8 +1043,8 @@ enumSelectChange(val) { const list = this.attributeDataTypePickList.find(item => item.key === val).values; this.form.rangeValue = list.join('\n'); - this.enumAddListChange=list; - this.form.defaultValue = list[0].replace('=',''); + this.enumAddListChange = list; + this.form.defaultValue = list[0].replace('=', ''); }, // 浣跨敤鏋氫妇switch婊戝潡change浜嬩欢 @@ -1001,12 +1053,12 @@ this.form.enumId = this.attributeDataTypePickList[0].key; const list = this.attributeDataTypePickList[0].values; this.form.rangeValue = list.join('\n'); - this.enumAddListChange=list; - this.form.defaultValue = list[0].replace('=',''); + this.enumAddListChange = list; + this.form.defaultValue = list[0].replace('=', ''); } else { this.form.defaultValue = ""; this.form.rangeValue = ""; - this.enumAddListChange=[]; + this.enumAddListChange = []; this.enumId = ""; } }, @@ -1111,7 +1163,7 @@ //鍒犻櫎鍊煎煙 handleRangeValueDel(val) { let currentRangeArray = this.form.rangeValue ? this.form.rangeValue.split('\n').filter(item => item.trim() !== val) : []; - this.enumAddListChange =currentRangeArray; + this.enumAddListChange = currentRangeArray; this.form.rangeValue = currentRangeArray.join('\n'); }, // 鍊煎煙绫诲瀷鍒囨崲 @@ -1256,8 +1308,8 @@ description: "", nullableFlag: true, attrLength: 50, - precisionLength:2,//绮惧害 - scaleLength:20,//闀垮害 + precisionLength: 2,//绮惧害 + scaleLength: 20,//闀垮害 enumFlag: false, enumId: "", enumSwitch: false, @@ -1282,10 +1334,10 @@ this.form.range = this.form.rangeValue ? this.form.rangeValue.replace(/\n/g, ';') : ''; if (this.form.attributeSelectType === 'business') { this.form.btmTypeId = this.form.referValue; - this.form.linkTypeName=""; + this.form.linkTypeName = ""; } else { this.form.linkTypeName = this.form.referValue; - this.form.btmTypeId=""; + this.form.btmTypeId = ""; } if (this.dialogTitle === 'add') { addAttribute(this.form).then(res => { @@ -1351,6 +1403,7 @@ width: 100%; } } + .margin-top { margin-top: 25px; } -- Gitblit v1.9.3