From e8c62bd430b9697d3f954125b7ec9f61f18347a2 Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期一, 20 十月 2025 11:19:34 +0800
Subject: [PATCH] 测试完成
---
src/views/knowledge/questionbank/particulars/index.vue | 469 +++++++++++++++++++++++++++++++++-------------------------
1 files changed, 265 insertions(+), 204 deletions(-)
diff --git a/src/views/knowledge/questionbank/particulars/index.vue b/src/views/knowledge/questionbank/particulars/index.vue
index 2a5cfa1..b009153 100644
--- a/src/views/knowledge/questionbank/particulars/index.vue
+++ b/src/views/knowledge/questionbank/particulars/index.vue
@@ -23,7 +23,7 @@
</div>
<div v-if="Editprogress == 1">
<el-card class="box-card">
- <el-form :inline="true" :model="topicobj" class="demo-form-inline">
+ <el-form :inline="true" ref="topicobj" :model="topicobj" :rules="rules" class="demo-form-inline">
<div class="headline">
鍩虹淇℃伅閰嶇疆
<span style="margin-left: 30px"
@@ -40,9 +40,27 @@
<el-divider></el-divider>
<div style="margin-left: 8%">
+ <el-form-item label="闂鍐呭" prop="scriptContent">
+ <el-input
+ style="width: 40vw"
+ type="textarea"
+ id="scriptContent"
+ v-model="topicobj.scriptContent"
+ @focus="handleInput('scriptContent')"
+ placeholder="璇疯緭鍏ラ棶棰樺唴瀹�"
+ ></el-input>
+ </el-form-item>
+ <el-form-item label="闂璇存槑" prop="targetname">
+ <el-input
+ style="width: 40vw"
+ type="textarea"
+ v-model="topicobj.scriptDesc"
+ placeholder="璇疯緭鍏ヨ鏄�"
+ ></el-input>
+ </el-form-item>
<el-row :gutter="10">
<el-col :span="8">
- <el-form-item label="闂鍒嗙被">
+ <el-form-item label="闂鍒嗙被" prop="categoryid">
<el-select
v-model="topicobj.categoryid"
size="medium"
@@ -66,7 +84,7 @@
</el-form-item>
</el-col>
<el-col :span="8">
- <el-form-item label="璇勪环绫诲瀷">
+ <el-form-item label="璇勪环绫诲瀷" prop="scoretype">
<el-select
v-model="topicobj.scoretype"
placeholder="璇烽�夋嫨鍒嗙被"
@@ -82,7 +100,7 @@
</el-form-item>
</el-col>
<el-col :span="8" v-if="topicobj.scoretype == 1">
- <el-form-item label="棰樼洰寰楀垎">
+ <el-form-item label="闂寰楀垎" prop="score">
<el-input
v-model="topicobj.score"
placeholder="璇疯緭鍏ュ垎鏁�"
@@ -93,16 +111,17 @@
<el-row :gutter="10">
<el-col :span="8"
- ><el-form-item label="棰樼洰鏍囬">
+ ><el-form-item label="闂鏍囬" prop="scriptTopic">
<el-input
v-model="topicobj.scriptTopic"
placeholder="璇疯緭鍏ユ爣棰�"
></el-input> </el-form-item
></el-col>
<el-col :span="8"
- ><el-form-item label="鏄惁鍙敤">
- <el-radio-group v-model="topicobj.isAvailable">
+ ><el-form-item label="鏄惁鍙敤" prop="isavailable">
+ <el-radio-group v-model="topicobj.isavailable">
<el-radio
+ @change="$forceUpdate()"
v-for="(item, index) in usable"
:label="item.value"
>{{ item.label }}</el-radio
@@ -110,40 +129,23 @@
</el-radio-group>
</el-form-item></el-col
>
- <el-col :span="8">
- <el-form-item label="鏄惁蹇呭~">
+ <!-- <el-col :span="8">
+ <el-form-item label="鏄惁蹇呭~" prop="ismandatory">
<el-radio-group v-model="topicobj.ismandatory">
<el-radio
+ @change="$forceUpdate()"
v-for="(item, index) in required"
:label="item.value"
>{{ item.label }}</el-radio
>
</el-radio-group>
</el-form-item>
- </el-col>
+ </el-col> -->
</el-row>
<el-row :gutter="10">
- <el-col :span="8">
- <el-form-item label="璇█">
- <el-select
- v-model="topicobj.language"
- size="medium"
- filterable
- placeholder="璇烽�夋嫨鍒嗙被"
- >
- <el-option
- class="topicobjaa"
- v-for="item in languagelist"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
+
<el-col :span="8"
- ><el-form-item label="棰樼洰绫诲瀷">
+ ><el-form-item label="闂绫诲瀷" prop="scriptType">
<el-select
v-model="topicobj.scriptType"
@change="changefn"
@@ -162,7 +164,7 @@
</el-select> </el-form-item
></el-col>
<el-col :span="8"
- ><el-form-item label="閫傜敤鏂瑰紡">
+ ><el-form-item label="閫傜敤鏂瑰紡" prop="suitway">
<el-select
v-model="topicobj.suitway"
disabled
@@ -177,17 +179,27 @@
>
</el-option> </el-select></el-form-item
></el-col>
+ <el-col :span="8">
+ <el-form-item label="璇█" prop="language">
+ <el-select
+ v-model="topicobj.language"
+ size="medium"
+ filterable
+ placeholder="璇烽�夋嫨鍒嗙被"
+ >
+ <el-option
+ class="topicobjaa"
+ v-for="item in languagelist"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ >
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
</el-row>
- <el-form-item label="棰樼洰鍐呭">
- <el-input
- style="width: 40vw"
- type="textarea"
- id="scriptContent"
- v-model="topicobj.scriptContent"
- @focus="handleInput('scriptContent')"
- placeholder="璇疯緭鍏ラ鐩唴瀹�"
- ></el-input>
- </el-form-item>
+
<!-- <el-form-item
label=""
prop="scriptContent"
@@ -233,14 +245,7 @@
</el-form-item>
</el-col>
</el-row> -->
- <el-form-item label="棰樼洰璇存槑">
- <el-input
- style="width: 40vw"
- type="textarea"
- v-model="topicobj.scriptDesc"
- placeholder="璇疯緭鍏ヨ鏄�"
- ></el-input>
- </el-form-item>
+
<!-- <el-form-item label="閫変腑鎸囨爣锛�">
<span style="margin-left: 30px"
@@ -323,7 +328,9 @@
<el-image
style="width: 100px; height: 100px"
:src="topicobj.picturePath"
- :preview-src-list="[...topicobj.picturePath]"
+ :preview-src-list="
+ topicobj.picturePath ? [topicobj.picturePath] : []
+ "
>
</el-image>
</div>
@@ -335,7 +342,7 @@
</div>
<div v-if="Editprogress == 2">
<el-card class="box-card">
- <el-form :inline="true" :model="topicobj" class="demo-form-inline">
+ <el-form :inline="true" ref="topicobj" :model="topicobj" class="demo-form-inline">
<div class="headline">
鎸囨爣璁剧疆璇︽儏
<span v-if="topicobj.targetname" style="margin-left: 30px"
@@ -348,6 +355,11 @@
topicobj.targetname ? "淇敼鎸囨爣" : "+閫夋嫨鎸囨爣"
}}</el-button></span
>
+ <span style="margin-left: 30px"
+ ><el-button type="primary" @click="Saveproblem"
+ >淇� 瀛�</el-button
+ >
+ </span>
</div>
<el-divider></el-divider>
<el-form ref="form">
@@ -376,7 +388,7 @@
<el-row>
<el-col :span="10">
- <el-form-item label="鍊肩被鍨�">
+ <el-form-item label="缁撴灉绫诲瀷">
<el-radio-group
:disabled="true"
v-model="topicobj.valueType"
@@ -388,7 +400,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="棰樼洰绫诲瀷">
+ <el-form-item label="闂棰樺瀷">
<el-radio-group
:disabled="true"
v-model="topicobj.scriptType"
@@ -401,122 +413,128 @@
</el-col>
</el-row>
</el-form>
- <div v-if="topicobj.scriptType != 4">
- <div class="headline">
- 閫夐」璁剧疆<span style="margin-left: 30px"
- ><el-button type="primary" round @click="addoption"
- >+鏂板</el-button
- ></span
- >
- </div>
+ <div>
<el-divider></el-divider>
+ <div v-if="topicobj.scriptType != 4">
+ <div class="headline">
+ 閫夐」璁剧疆<span style="margin-left: 30px"
+ ><el-button type="primary" round @click="addoption"
+ >+鏂板</el-button
+ ></span
+ >
+ </div>
+ <div
+ class="topicxq"
+ v-for="item in topicobj.svyLibScriptOptions"
+ v-if="item.isoperation != 3"
+ >
+ <el-row :gutter="10">
+ <el-col :span="11"
+ ><el-form-item label="閫夐」鍚嶇О">
+ <el-input
+ type="text"
+ placeholder="璇疯緭鍏ラ�夐」鍒嗗��"
+ v-model="item.optioncontent"
+ show-word-limit
+ >
+ </el-input> </el-form-item
+ ></el-col>
+ <el-col :span="11">
+ <el-form-item v-if="topicobj.scoretype == 1" label="鍒嗗��">
+ <el-input
+ type="text"
+ placeholder="璇疯緭鍏ラ�夐」鍒嗗��"
+ v-model="item.score"
+ show-word-limit
+ >
+ </el-input>
+ </el-form-item>
+ <el-form-item
+ v-else-if="topicobj.scoretype == 2"
+ label="ABC绛夌骇"
+ >
+ <el-radio-group v-model="item.score">
+ <el-radio :label="1">A</el-radio>
+ <el-radio :label="2">B</el-radio>
+ <el-radio :label="3">C</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ <el-form-item
+ v-else-if="topicobj.scoretype == 3"
+ label="浼樿壇绛夌骇"
+ >
+ <el-radio-group v-model="item.score">
+ <el-radio label="浼�">浼�</el-radio>
+ <el-radio label="鑹�">鑹�</el-radio>
+ <el-radio label="宸�">宸�</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-col>
- <div
- class="topicxq"
- v-for="item in topicobj.svyLibScriptOptions"
- v-if="item.isoperation != 3"
- >
- <el-row :gutter="10">
- <el-col :span="11"
- ><el-form-item label="閫夐」鍚嶇О">
- <el-input
- type="text"
- placeholder="璇疯緭鍏ラ�夐」鍒嗗��"
- v-model="item.optioncontent"
- show-word-limit
- >
- </el-input> </el-form-item
- ></el-col>
- <el-col :span="11">
- <el-form-item v-if="topicobj.scoretype == 1" label="鍒嗗��">
- <el-input
- type="text"
- placeholder="璇疯緭鍏ラ�夐」鍒嗗��"
- v-model="item.score"
- show-word-limit
- >
- </el-input>
- </el-form-item>
- <el-form-item
- v-else-if="topicobj.scoretype == 2"
- label="ABC绛夌骇"
+ <el-col
+ :span="2"
+ :offsset="topicobj.scoretype == 4 ? 11 : 0"
>
- <el-radio-group v-model="item.score">
- <el-radio label="A">A</el-radio>
- <el-radio label="B">B</el-radio>
- <el-radio label="C">C</el-radio>
+ <el-button
+ type="danger"
+ icon="el-icon-delete"
+ circle
+ @click="deletexuanx(item)"
+ ></el-button>
+ </el-col>
+ </el-row>
+ <el-row :gutter="10">
+ <el-form-item label="寮傚父鎻愰啋">
+ <el-radio-group v-model="item.isabnormal">
+ <el-radio :label="1">鏄�</el-radio>
+ <el-radio :label="0">鍚�</el-radio>
</el-radio-group>
</el-form-item>
- <el-form-item
- v-else-if="topicobj.scoretype == 3"
- label="浼樿壇绛夌骇"
- >
- <el-radio-group v-model="item.score">
- <el-radio label="浼�">浼�</el-radio>
- <el-radio label="鑹�">鑹�</el-radio>
- <el-radio label="宸�">宸�</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-col>
-
- <el-col :span="2" :offsset="topicobj.scoretype == 4 ? 11 : 0">
- <el-button
- type="danger"
- icon="el-icon-delete"
- circle
- @click="deletexuanx(item)"
- ></el-button>
- </el-col>
- </el-row>
- <el-row :gutter="10">
- <el-form-item label="棰勮鎻愰啋">
- <el-radio-group v-model="item.isabnormal">
- <el-radio :label="1">鏄�</el-radio>
- <el-radio :label="0">鍚�</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-row>
- <el-row :gutter="10">
- <el-form-item label="閫変腑鎻愮ず">
- <el-input
- style="width: 40vw"
- type="textarea"
- autosize
- placeholder="璇疯緭鍏ュ唴瀹�"
- v-model="item.prompt"
- >
- </el-input
- ></el-form-item>
- </el-row>
- <el-form-item label="閫夐」鏂囦欢" prop="sickness">
- <div style="width: 40vw">
- <el-upload
- class="upload-demo"
- :action="uploadImgUrl"
- :headers="headers"
- accept=".jpg,.png,image/*"
- :on-success="handleChange.bind(this, item)"
- >
- <el-button size="small" type="primary"
- >鐐瑰嚮涓婁紶</el-button
+ </el-row>
+ <el-row :gutter="10">
+ <el-form-item label="閫変腑鎻愮ず">
+ <el-input
+ style="width: 40vw"
+ type="textarea"
+ autosize
+ placeholder="璇疯緭鍏ュ唴瀹�"
+ v-model="item.prompt"
>
- </el-upload>
- <div style="margin: 20px">
- <el-image
- style="width: 100px; height: 100px"
- :src="item.picturePath"
- :preview-src-list="[...item.picturePath]"
+ </el-input
+ ></el-form-item>
+ </el-row>
+ <el-form-item label="閫夐」鏂囦欢" prop="sickness">
+ <div style="width: 40vw">
+ <el-upload
+ class="upload-demo"
+ :action="uploadImgUrl"
+ :headers="headers"
+ accept=".jpg,.png,image/*"
+ :on-success="handleChange.bind(this, item)"
>
- </el-image>
+ <el-button size="small" type="primary"
+ >鐐瑰嚮涓婁紶</el-button
+ >
+ </el-upload>
+ <div style="margin: 20px">
+ <el-image
+ style="width: 100px; height: 100px"
+ :src="item.picturePath"
+ :preview-src-list="
+ item.picturePath ? [item.picturePath] : []
+ "
+ >
+ </el-image>
+ </div>
</div>
- </div>
- </el-form-item>
+ </el-form-item>
+ </div>
</div>
<div v-else class="topicxq">
<el-input
type="textarea"
:rows="4"
- placeholder="姝ゅ灞曠ず鏀堕泦淇℃伅"
+ placeholder="姝ゅ灞曠ず闂瓟棰樻敹闆嗕俊鎭�"
v-model="testgovalue"
>
</el-input>
@@ -600,21 +618,13 @@
:show-overflow-tooltip="true"
/>
<el-table-column
- label="璇█"
- align="center"
- key="language"
- prop="language"
- width="200"
- :show-overflow-tooltip="true"
- />
- <el-table-column
label="鏄惁鍙敤"
align="center"
- key="isAvailable"
- prop="isAvailable"
+ key="isavailable"
+ prop="isavailable"
>
<template slot-scope="scope">
- <dict-tag :options="usable" :value="scope.row.isAvailable" />
+ <dict-tag :options="usable" :value="scope.row.isavailable" />
</template>
</el-table-column>
<el-table-column
@@ -663,7 +673,7 @@
/>
</div>
</el-drawer>
- <el-dialog title="棰樼洰棰勮" :visible.sync="topicVisible" width="50%">
+ <el-dialog title="闂棰勮" :visible.sync="topicVisible" width="50%">
<div class="preview-left">
<div class="dev-text">
<span>{{ topicobj.scriptContent }}</span>
@@ -721,6 +731,8 @@
svyLibScriptOptions: [],
svyLibScriptTagList: [],
suitway: "1",
+ scoretype:'4',
+ language:'鏅�氳瘽',
},
headers: {
Authorization: "Bearer " + getToken(),
@@ -763,6 +775,7 @@
{ value: "scriptTopic", table: "scriptTopic" },
],
inputValueillness: "",
+ testgovalue: "",
required: [],
themelist: [],
languagelist: [],
@@ -787,6 +800,36 @@
valuetype: [],
usable: [],
mode: [], //鏂瑰紡
+ // 琛ㄥ崟鏍¢獙
+ rules: {
+ categoryid: [
+ { required: true, message: "闂鍒嗙被涓嶈兘涓虹┖", trigger: "blur" },
+ ],
+ scoretype: [
+ { required: true, message: "璇勪环绫诲瀷涓嶈兘涓虹┖", trigger: "blur" },
+ ],
+ language: [
+ { required: true, message: "璇█涓嶈兘涓虹┖", trigger: "blur" },
+ ],
+ isavailable: [
+ { required: true, message: "鍙敤鐘舵�佷笉鑳戒负绌�", trigger: "blur" },
+ ],
+ scriptTopic: [
+ { required: true, message: "闂鏍囬涓嶈兘涓虹┖", trigger: "blur" },
+ ],
+ ismandatory: [
+ { required: true, message: "鏄惁蹇呭~涓嶈兘涓虹┖", trigger: "blur" },
+ ],
+ scriptType: [
+ { required: true, message: "闂绫诲瀷涓嶈兘涓虹┖", trigger: "blur" },
+ ],
+ suitway: [
+ { required: true, message: "閫傜敤鏂瑰紡涓嶈兘涓虹┖", trigger: "blur" },
+ ],
+ scriptContent: [
+ { required: true, message: "闂鍐呭涓嶈兘涓虹┖", trigger: "blur" },
+ ],
+ },
};
},
@@ -829,15 +872,14 @@
// 鑾峰彇鏁版嵁
getissueinfo() {
this.id = this.$route.query.id;
- this.topicobj.categoryid = Number(this.$route.query.categoryid);
- console.log(this.topicobj.categoryid);
- this.topicobj.isavailable = "1";
- this.topicobj.language = "鏅�氳瘽";
+
// 鍒嗙被
getissueclassify({}).then((res) => {
this.classifylist = res.rows;
- console.log(this.classifylist, "鍒嗙被");
+ if (this.$route.query.categoryid) {
+ this.topicobj.categoryid = Number(this.$route.query.categoryid);
+ }
});
if (!this.id) {
return;
@@ -879,7 +921,9 @@
},
// 鏂板鎴栦慨鏀硅鎯�
compileissue() {
- this.topicobj.svyLibScriptOptions = this.topicobj.svyLibScriptOptions.map(
+ this.$refs["topicobj"].validate((valid) => {
+ if (valid) {
+ this.topicobj.svyLibScriptOptions = this.topicobj.svyLibScriptOptions.map(
(item) => {
if (item.isoperation != 1 && item.isoperation != 3) {
item.isoperation = 2;
@@ -933,39 +977,62 @@
if (this.illnesslistapi.length) {
deltargetillness(this.illnesslistapi.join(",")).then((res) => {});
}
+ }
+ })
+
+
},
// 鍒ゆ柇鍒嗗��
Scorejudgment() {
let scorearr = this.topicobj.svyLibScriptOptions;
- let isValid = scorearr.every((score) => {
- if (score.score) {
- console.log(Number(score.score), this.topicobj.score, "鍒嗗��");
- if (
- Number(score.score) < 0 ||
- Number(score.score) > Number(this.topicobj.score)
- ) {
- console.log(score, "閿欒鍒嗗��");
+ let isValid = scorearr.every((score, index) => {
+ if (this.topicobj.scriptType == 1) {
+ if (score.score||score.score==0) {
+ if (
+ Number(score.score) < 0 ||
+ Number(score.score) > Number(this.topicobj.score)
+ ) {
+ console.log(score, "閿欒鍒嗗��");
+ this.$message({
+ message: "閫夐」鍒嗗�煎繀椤诲湪0鍒�" + this.topicobj.score + "鍒嗕箣闂�",
+ type: "warning",
+ });
+ return false;
+ }
+ return true;
+ } else {
this.$message({
- message: "閫夐」鍒嗗�煎繀椤诲湪0鍒�" + this.topicobj.score + "鍒嗕箣闂�",
+ message: "閫夐」鍒嗗�兼湭璁剧疆",
type: "warning",
});
return false;
}
+ } else if (this.topicobj.scriptType == 2) {
+ // 绱姞鍒嗗��
+ const totalScore = scorearr.reduce((acc, score) => {
+ if (score.score) {
+ return acc + Number(score.score);
+ }
+ return acc; // 濡傛灉 score.score 涓嶅瓨鍦紝涓嶇疮鍔�
+ }, 0);
+
+ // 妫�鏌ョ疮鍔犵殑鍒嗗�兼槸鍚︾瓑浜� this.topicobj.score
+ if (totalScore !== Number(this.topicobj.score)) {
+ this.$message({
+ message:
+ "澶氶�夐閫夐」鍒嗗�兼�诲拰蹇呴』绛変簬 " + this.topicobj.score + " 鍒�",
+ type: "warning",
+ });
+ return false;
+ }
+ return true; // 濡傛灉鎬诲垎姝g‘锛岃繑鍥� true
+ } else if (this.topicobj.scriptType == 4) {
return true;
- } else if (this.topicobj.scriptType == 3) {
- return true;
- } else {
- this.$message({
- message: "閫夐」鍒嗗�兼湭璁剧疆",
- type: "warning",
- });
- return false;
}
});
if (isValid) {
this.compileissue();
- // console.log("鍒颁繚瀛樹簡");
}
},
Saveproblem() {
@@ -978,13 +1045,14 @@
// 鍒ゆ柇鎸囨爣
changefn(item) {
console.log(item);
-
if (this.topicobj.targetname || this.topicobj.svyLibScriptOptions[0]) {
this.$modal
.confirm("鏇存敼绫诲瀷鍚庨�夐」灏嗘竻绌烘槸鍚︾户缁紵")
.then(() => {
this.scriptTypels = this.topicobj.scriptType;
- this.topicobj.svyLibScriptOptions = [];
+ this.topicobj.svyLibScriptOptions.forEach((item) => {
+ item.isoperation = 3;
+ });
})
.catch(() => {
this.topicobj.scriptType = this.scriptTypels;
@@ -1001,8 +1069,6 @@
console.log(this.topicobj.svyLibScriptOptions);
if (this.topicobj.svyLibScriptOptions[index].id) {
- console.log(2);
-
this.topicobj.svyLibScriptOptions[index].isoperation = 3;
} else {
this.topicobj.svyLibScriptOptions.splice(index, 1);
@@ -1026,14 +1092,12 @@
)
.then(() => {
console.log(row);
- this.topicobj.scriptTopic = row.targetname;
+ // this.topicobj.scriptTopic = row.targetname;
this.topicobj.valueType = row.valueType;
this.topicobj.scriptType = row.scriptType;
- this.topicobj.scriptContent = row.targetdesc;
+ // this.topicobj.scriptContent = row.targetdesc;
this.topicobj.targetid = row.id;
this.topicobj.targetname = row.targetname;
- this.topicobj.isavailable = "0";
- this.topicobj.language = "鏅�氳瘽";
this.topicobj.svyLibScriptOptions = [];
const labellist = row.targetoptionList;
labellist.forEach((item) => {
@@ -1055,12 +1119,10 @@
tagcategoryid: "0",
};
listtag(tagqueryParams).then((response) => {
- console.log(response, "寰呴�夋爣绛�");
this.optionstag = response.rows;
});
},
handleClosetag(tag) {
- console.log(tag);
console.log(this.dynamicTags.indexOf(tag));
const lindex = this.dynamicTags.indexOf(tag);
this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);
@@ -1331,8 +1393,7 @@
border-radius: 4px;
margin-top: 15px;
margin-left: 10%;
- padding-left: 20px;
- padding-top: 15px;
+ padding: 20px;
border: 1px solid #dcdfe6;
-webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
0 0 6px 0 rgba(0, 0, 0, 0.04);
--
Gitblit v1.9.3