Browse Source

111

shibei_master
jiangyy 3 years ago
parent
commit
af1828e8bf
  1. BIN
      src/assets/img/caiji-bc.png
  2. BIN
      src/assets/img/logo.png
  3. 2
      src/assets/scss/modules/visual/communityManage.scss
  4. 60
      src/assets/scss/pages/caiji.scss
  5. 4
      src/views/modules/base/community/buildTable.vue
  6. 19
      src/views/modules/base/community/community.vue
  7. 4
      src/views/modules/base/community/communityTable.vue
  8. 11
      src/views/modules/base/community/roomForm.vue
  9. 4
      src/views/modules/base/community/roomTable.vue
  10. 6
      src/views/modules/base/epidemic/natFocus/natFocusAdd.vue
  11. 167
      src/views/modules/base/epidemic/natFocus/natFocusList.vue
  12. 33
      src/views/modules/base/epidemic/veroFocus/veroFocusAdd.vue
  13. 12
      src/views/modules/base/epidemic/veroFocus/veroFocusEdit.vue
  14. 206
      src/views/modules/base/epidemic/veroFocus/veroFocusList.vue
  15. 4
      src/views/modules/communityParty/regionalParty/activitys.vue
  16. 27
      src/views/pages/caiji.vue
  17. 76
      src/views/pages/caijisuccess.vue

BIN
src/assets/img/caiji-bc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
src/assets/img/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

2
src/assets/scss/modules/visual/communityManage.scss

@ -18,7 +18,7 @@
}
}
.div_table {
.div_table_item {
margin-top: 20px;
position: relative;
}

60
src/assets/scss/pages/caiji.scss

@ -1,4 +1,5 @@
.bg-caiji {
background-color: rgba(189, 214, 255, 0.89);
height: 100%;
width: 100vw;
@ -50,15 +51,66 @@
}
.bg-caiji-success {
background: url("../../assets/img/caiji-bc.png") no-repeat;
background-size: 100% 100%;
height: 100vh;
width: 100vw;
text-align: center;
.title {
background-color: rgba(189, 214, 255, 0.89);
padding: 20px;
// background-color: rgba(189, 214, 255, 0.89);
padding-top:30px;
font-size: 18px;
font-family: PingFang SC;
font-weight: 800;
color: #333333;
display: flex;
height:25px;
align-items: center;
justify-content: center;
>img{
width:27px;
height:25px;
}
.title_name{
margin-left:5px;
margin-top:5px;
}
}
.div_tip{
text-align: center;
font-size: 20px;
margin-top:35px;
font-size: 18px;
font-family: PingFang SC;
font-weight: 800;
color: #2E78E2;
line-height: 26px;
}
.div_content{
margin:20px 10px 30px 10px;
padding:20px 16px;
background: #FFFFFF;
border-radius: 10px;
font-size: 16px;
font-family: Source Han Serif SC;
font-weight: 400;
color: #333333;
line-height: 30px;
text-align: left;
.content_long{
display: flex;
justify-content: left;
align-items: flex-start;
.content_title{
flex:0 0 80px;
}
}
}
.main {

4
src/views/modules/base/community/buildTable.vue

@ -54,7 +54,7 @@
@click="deleteBatch">批量删除</el-button>
</div>
<div class="div_table">
<div class="div_table_item">
<el-table ref="ref_table"
:data="tableData"
:header-cell-style="{background:'#2195FE',color:'#FFFFFF'}"
@ -190,7 +190,7 @@ export default {
computed: {
tableHeight () {
return this.$store.state.inIframe ? this.clientHeight - 270 + this.iframeHeight : this.clientHeight - 270
return this.$store.state.inIframe ? this.clientHeight - 310 + this.iframeHeight : this.clientHeight - 310
},

19
src/views/modules/base/community/community.vue

@ -15,8 +15,8 @@
:props="defaultProps"
:highlight-current="true"
node-key="id"
:default-expanded-keys="openNodes"
:expand-on-click-node="false"
default-expand-all
:filter-node-method="filterNode"
@node-click="handleNodeClick">
</el-tree>
@ -123,6 +123,7 @@ export default {
filterText: '',
treeLoading: true,
treeData: [],
openNodes: [],
defaultProps: {
children: 'children',
label: 'showName'
@ -160,8 +161,10 @@ export default {
},
async mounted () {
this.treeLoading = true
await this.loadOrgData()
await this.loadTree()
await this.loadOpenNode()
await this.$refs['ref_communityTable'].loadTable(true, this.selTreeObj)
if (this.treeData.length > 0) {
@ -213,6 +216,20 @@ export default {
// this.loadTable()
},
async loadOpenNode () {
const url = "/gov/org/building/tree-ids"
let params = {}
const { data, code, msg } = await requestPost(url, params)
if (code === 0) {
this.openNodes = data
} else {
this.$message.error(msg)
}
},
async loadTree (isRefresh) {
const url = "/gov/org/building/treelist"
let params = {}

4
src/views/modules/base/community/communityTable.vue

@ -78,7 +78,7 @@
</div>
<div class="div_table">
<div class="div_table_item">
<el-table ref="ref_table"
:data="tableData"
border
@ -237,7 +237,7 @@ export default {
computed: {
tableHeight () {
return this.$store.state.inIframe ? this.clientHeight - 300 + this.iframeHeight : this.clientHeight - 300
return this.$store.state.inIframe ? this.clientHeight - 310 + this.iframeHeight : this.clientHeight - 310
},

11
src/views/modules/base/community/roomForm.vue

@ -180,11 +180,12 @@ export default {
this.dataForm.buildingUnitId = this.dataForm.unitNumKey
this.houseType = this.dataForm.houseTypeKey
this.purpose = this.dataForm.purposeKey
if (this.dataForm.rentFlagKey) {
this.rentFlag = 1
} else {
this.rentFlag = 0
}
this.rentFlag = parseInt(this.dataForm.rentFlagKey)
// if (this.dataForm.rentFlagKey==='2') {
// this.rentFlag = parseInt(this.dataForm.rentFlagKey)
// } else {
// this.rentFlag = 0
// }
}

4
src/views/modules/base/community/roomTable.vue

@ -36,7 +36,7 @@
@click="deleteBatch">批量删除</el-button>
</div>
<div class="div_table">
<div class="div_table_item ">
<el-table ref="ref_table"
:data="tableData"
:header-cell-style="{background:'#2195FE',color:'#FFFFFF'}"
@ -208,7 +208,7 @@ export default {
},
computed: {
tableHeight () {
return this.$store.state.inIframe ? this.clientHeight - 270 + this.iframeHeight : this.clientHeight - 270
return this.$store.state.inIframe ? this.clientHeight - 310 + this.iframeHeight : this.clientHeight - 310
},

6
src/views/modules/base/epidemic/natFocus/natFocusAdd.vue

@ -198,6 +198,12 @@
label="身份证"
min-width="170">
</el-table-column>
<el-table-column prop="houseName"
header-align="center"
align="center"
label="所属房屋"
min-width="170">
</el-table-column>
<el-table-column prop="natCount"
header-align="center"
align="center"

167
src/views/modules/base/epidemic/natFocus/natFocusList.vue

@ -59,6 +59,74 @@
</el-form-item>
</div>
<div>
<el-form-item label="所属房屋">
<div class="resi-cell-value">
<div class="resi-cell-col">
<el-form-item prop="villageId">
<el-select v-model.trim="formData.villageId"
placeholder="小区"
size="small"
clearable
class="resi-cell-select"
@change="handleChangeV">
<el-option v-for="item in optionsV"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="buildId">
<el-select v-model.trim="formData.buildId"
placeholder="楼号"
:disabled="!this.formData.villageId"
size="small"
clearable
class="resi-cell-select resi-cell-select-middle list_item_width_1"
@change="handleChangeB">
<el-option v-for="item in optionsB"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="unitId">
<el-select v-model.trim="formData.unitId"
placeholder="单元"
size="small"
:disabled="!this.formData.buildId"
clearable
class="resi-cell-select resi-cell-select-middle list_item_width_1"
@change="handleChangeD">
<el-option v-for="item in optionsD"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="homeId">
<el-select v-model.trim="formData.homeId"
placeholder="房号"
:disabled="!this.formData.unitId"
size="small"
clearable
class="resi-cell-select resi-cell-select-middle list_item_width_1">
<el-option v-for="item in optionsH"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</div>
</div>
</el-form-item>
<el-button style="margin-left:30px"
size="small"
class="diy-button--search"
@ -145,6 +213,12 @@
label="身份证"
min-width="170">
</el-table-column>
<el-table-column prop="roomShow"
header-align="center"
align="center"
label="所属房屋"
min-width="170">
</el-table-column>
<el-table-column prop="reason"
header-align="center"
align="center"
@ -325,7 +399,16 @@ export default {
idCard: '',
remark: '',
reason: '',
villageId: '',
buildId: '',
unitId: '',
homeId: ''
},
optionsV: [],
optionsB: [],
optionsH: [],
optionsD: [],
natNumList: [],
tableData: [],
@ -400,6 +483,90 @@ export default {
this.tableLoading = false
},
handleChangeV (val) {
console.log('val', val)
this.formData.buildId = ''
this.formData.unitId = ''
this.formData.homeId = ''
this.getBuildList()
this.getUniList()
this.getHouseList()
},
handleChangeB (val) {
console.log('val', val)
this.formData.unitId = ''
this.formData.homeId = ''
this.getUniList()
this.getHouseList()
},
handleChangeD () {
this.formData.homeId = ''
this.getHouseList()
},
getValiheList () {
const { user } = this.$store.state
this.$http
.post('/gov/org/icneighborhood/neighborhoodoption', { gridId: this.formData.GRID_ID, agencyId: user.agencyId })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log('获取查询详情成功', res.data)
this.optionsV = res.data
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
getBuildList () {
this.$http
.post('/gov/org/icbuilding/buildingoption', { neighborHoodId: this.formData.villageId })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log('获取查询详情成功', res.data)
this.optionsB = res.data
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
getUniList () {
this.$http
.post('/gov/org/icbuildingunit/unitoption', { buildingId: this.formData.buildId })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log('获取查询详情成功', res.data)
this.optionsD = res.data
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
getHouseList () {
this.$http
.post('/gov/org/ichouse/houseoption', { unitId: this.formData.unitId })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log('获取查询详情成功', res.data)
this.optionsH = res.data
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
handleSelectTable (selection, row) {
row.isSel = !row.isSel

33
src/views/modules/base/epidemic/veroFocus/veroFocusAdd.vue

@ -46,6 +46,18 @@
v-model="formData1.idCard">
</el-input>
</el-form-item>
<el-form-item label="关注原因"
prop="reason"
label-width="150px"
style="display: block">
<el-input class="item_width_1"
placeholder="请输入关注原因"
clearable
v-model="formData1.reason">
</el-input>
</el-form-item>
<el-form-item label="备注"
prop="remark"
label-width="150px"
@ -172,6 +184,12 @@
label="身份证"
min-width="170">
</el-table-column>
<el-table-column prop="houseName"
header-align="center"
align="center"
label="所属房屋"
min-width="170">
</el-table-column>
<el-table-column prop="vaccineCount"
header-align="center"
align="center"
@ -219,6 +237,17 @@
:model="formData2"
ref="ref_form2"
:label-width="'90px'">
<el-form-item label="关注原因"
prop="reason"
label-width="100px"
style="display: block">
<el-input class="item_width_1"
placeholder="请输入关注原因"
clearable
v-model="formData2.reason">
</el-input>
</el-form-item>
<el-form-item label="备注"
prop="remark"
@ -317,6 +346,7 @@ export default {
isSelChannel: false,
channel: [],
content: '',
reason: '',
},
@ -326,6 +356,7 @@ export default {
isSelChannel: false,
channel: [],
content: '',
reason: '',
},
tableData: [],
total: 0,
@ -661,6 +692,7 @@ export default {
channel: [],
content: '',
attentionType: 1,
reason: '',
}
this.formData2 = {
@ -669,6 +701,7 @@ export default {
isSelChannel: false,
channel: [],
content: '',
reason: '',
}
this.formDataSearch = {
gridId: '',

12
src/views/modules/base/epidemic/veroFocus/veroFocusEdit.vue

@ -44,6 +44,16 @@
v-model="formData.idCard">
</el-input> -->
</el-form-item>
<el-form-item label="关注原因"
prop="reason"
label-width="150px"
style="display: block">
<el-input class="item_width_1"
placeholder="请输入关注原因"
clearable
v-model="formData.reason">
</el-input>
</el-form-item>
<el-form-item label="备注"
prop="remark"
label-width="150px"
@ -135,6 +145,7 @@ export default {
isSelChannel: false,
channel: [],
content: '',
reason: '',
},
}
@ -223,6 +234,7 @@ export default {
isSelChannel: false,
channel: [],
content: '',
reason: '',
}
},

206
src/views/modules/base/epidemic/veroFocus/veroFocusList.vue

@ -54,6 +54,73 @@
</el-form-item>
</div>
<div>
<el-form-item label="所属房屋">
<div class="resi-cell-value">
<div class="resi-cell-col">
<el-form-item prop="villageId">
<el-select v-model.trim="formData.villageId"
placeholder="小区"
size="small"
clearable
class="resi-cell-select"
@change="handleChangeV">
<el-option v-for="item in optionsV"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="buildId">
<el-select v-model.trim="formData.buildId"
placeholder="楼号"
:disabled="!this.formData.villageId"
size="small"
clearable
class="resi-cell-select resi-cell-select-middle list_item_width_1"
@change="handleChangeB">
<el-option v-for="item in optionsB"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="unitId">
<el-select v-model.trim="formData.unitId"
placeholder="单元"
size="small"
:disabled="!this.formData.buildId"
clearable
class="resi-cell-select resi-cell-select-middle list_item_width_1"
@change="handleChangeD">
<el-option v-for="item in optionsD"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="homeId">
<el-select v-model.trim="formData.homeId"
placeholder="房号"
:disabled="!this.formData.unitId"
size="small"
clearable
class="resi-cell-select resi-cell-select-middle list_item_width_1">
<el-option v-for="item in optionsH"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</div>
</div>
</el-form-item>
<el-button style="margin-left:30px"
size="small"
class="diy-button--search"
@ -140,18 +207,31 @@
label="身份证"
min-width="170">
</el-table-column>
<el-table-column prop="roomShow"
header-align="center"
align="center"
label="所属房屋"
min-width="170">
</el-table-column>
<el-table-column prop="vaccinationCount"
header-align="center"
align="center"
label="接种针次"
width="100">
</el-table-column>
<el-table-column prop="reason"
header-align="center"
align="center"
show-overflow-tooltip
label="关注原因"
min-width="230">
</el-table-column>
<el-table-column prop="remark"
header-align="center"
align="center"
show-overflow-tooltip
label="备注"
min-width="230">
min-width="200">
</el-table-column>
<el-table-column prop="lastInformTime"
header-align="center"
@ -319,7 +399,16 @@ export default {
mobile: '',
idCard: '',
vaccinationCount: '',
villageId: '',
buildId: '',
unitId: '',
homeId: ''
},
optionsV: [],
optionsB: [],
optionsH: [],
optionsD: [],
veroNumList: [],
tableData: [],
@ -345,6 +434,8 @@ export default {
this.$refs['ref_table'].doLayout()
},
async mounted () {
const { user } = this.$store.state
this.agencyId = user.agencyId
for (let i = 0; i < 11; i++) {
let obj = {
value: i + '',
@ -352,7 +443,7 @@ export default {
}
this.veroNumList.push(obj)
}
this.getValiheList()
await this.loadTable()
},
@ -381,19 +472,118 @@ export default {
this.analysisTableSelection()
// this.tableData.forEach(item => {
// if (item.time) {
// let timeArray = item.time.split(' ')
// item.time = timeArray[0]
// }
this.tableData.forEach(item => {
item.roomShow = ''
if (!item.villageName && !item.buildName && !item.unitName && !item.homeName) {
item.roomShow = '--'
} else {
if (item.villageName) {
item.roomShow = item.roomShow + item.villageName
}
if (item.buildName) {
item.roomShow = item.roomShow + item.buildName
}
if (item.unitName) {
item.roomShow = item.roomShow + item.unitName
}
if (item.villageName) {
item.roomShow = item.homeName + item.homeName
}
}
// });
});
} else {
this.$message.error(msg)
}
this.tableLoading = false
},
handleChangeV (val) {
console.log('val', val)
this.formData.buildId = ''
this.formData.unitId = ''
this.formData.homeId = ''
this.getBuildList()
this.getUniList()
this.getHouseList()
},
handleChangeB (val) {
console.log('val', val)
this.formData.unitId = ''
this.formData.homeId = ''
this.getUniList()
this.getHouseList()
},
handleChangeD () {
this.formData.homeId = ''
this.getHouseList()
},
getValiheList () {
const { user } = this.$store.state
this.$http
.post('/gov/org/icneighborhood/neighborhoodoption', { gridId: this.formData.GRID_ID, agencyId: user.agencyId })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log('获取查询详情成功', res.data)
this.optionsV = res.data
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
getBuildList () {
this.$http
.post('/gov/org/icbuilding/buildingoption', { neighborHoodId: this.formData.villageId })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log('获取查询详情成功', res.data)
this.optionsB = res.data
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
getUniList () {
this.$http
.post('/gov/org/icbuildingunit/unitoption', { buildingId: this.formData.buildId })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log('获取查询详情成功', res.data)
this.optionsD = res.data
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
getHouseList () {
this.$http
.post('/gov/org/ichouse/houseoption', { unitId: this.formData.unitId })
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log('获取查询详情成功', res.data)
this.optionsH = res.data
}
})
.catch(() => {
return this.$message.error('网络错误')
})
},
handleSelectTable (selection, row) {
row.isSel = !row.isSel

4
src/views/modules/communityParty/regionalParty/activitys.vue

@ -139,10 +139,10 @@
label="单位名称"
width="180">
</el-table-column>
<el-table-column prop="所属网格"
<el-table-column prop="gridName"
header-align="center"
align="center"
label="单位名称"
label="所属网格"
width="180">
</el-table-column>
<el-table-column prop="title"

27
src/views/pages/caiji.vue

@ -142,6 +142,18 @@
type="tel"
v-model="item.mobile"></mt-field>
<div class="line"></div>
<mt-field class="my-field"
:disableClear="true"
:label="'户籍所在地'"
placeholder="请输入"
v-model="item.domicilePlace"></mt-field>
<div class="line"></div>
<mt-field class="my-field"
:disableClear="true"
:label="'学校或单位'"
placeholder="请输入"
v-model="item.workPlace"></mt-field>
<div class="line"></div>
<div @click="handelSel('detNum',index)">
<mt-cell :title="'参加核酸检测次数'"
@ -262,6 +274,8 @@ export default {
{
name: '',
mobile: '',
domicilePlace: '',
workPlace: '',
idNum: '',
customerId: '',
heSuanCount: null,
@ -648,7 +662,12 @@ export default {
this.btnDisabled = false
if (code === 0) {
this.$router.replace({ name: 'caijisuccess' })
this.$router.replace({
name: 'caijisuccess',
query: {
formData: this.formData
}
})
// Toast({
// message: '',
// duration: 3000
@ -727,7 +746,7 @@ export default {
let member1 = this.memberList[0]
if (!member1.name || !member1.mobile || !member1.idNum || !member1.selDetNum.value || !member1.selDetCondition.value) {
if (!member1.name || !member1.mobile || !member1.domicilePlace || !member1.workPlace || !member1.idNum || !member1.selDetNum.value || !member1.selDetCondition.value) {
aletMessage = '请完整填写用户1信息'
return aletMessage
}
@ -736,7 +755,7 @@ export default {
for (let i = 1; i < this.memberList.length; i++) {
let item = this.memberList[i]
if (item.name || item.mobile || item.idNum || item.selDetNum.value || item.selDetCondition.value) {//
if (item.name || item.mobile || item.domicilePlace || item.workPlace || item.idNum || item.selDetNum.value || item.selDetCondition.value) {//
if (!item.name || !item.idNum) {
aletMessage = '请完整填写用户' + (i + 1) + '的姓名和身份证信息'
return aletMessage
@ -828,6 +847,8 @@ export default {
let objTemp = {
name: '',
mobile: '',
domicilePlace: '',
workPlace: '',
idNum: '',
heSuanCount: null,
ymjz: '',

76
src/views/pages/caijisuccess.vue

@ -1,17 +1,50 @@
<template>
<div class="bg-caiji-success">
<div class="title">
居民信息填报
<img src="@/assets/img/logo.png">
<div class="title_name">居民信息填报</div>
</div>
<div class="main">
<div class="div_tip">
<div>提交成功</div>
<div>请截图保存方便核验人员查看</div>
</div>
<div class="div_content">
<div class="content_long">
<div class="content_title">所属房屋</div>
<div>{{formData.address}}</div>
</div>
<div>
<span>房主姓名</span>
<span>{{formData.houseHolderName}}</span>
</div>
<div v-for="(item,index) in formData.memberList"
:key="index">
<div>
<span>成员{{index+1}}</span>
<span>{{item.name}}</span>
</div>
<div>
<span>身份证号</span>
<span>{{item.idNum}}</span>
</div>
<div>
<span>手机号</span>
<span>{{item.mobile}}</span>
</div>
</div>
</div>
<!-- <div class="main">
<div class="icon-success">
<i class="el-icon-circle-check "></i>
</div>
<div class="success-content"> 提交成功</div>
</div>
</div> -->
</div>
</template>
<script>
@ -26,7 +59,7 @@ export default {
data () {
return {
formData: {},
}
},
components: {},
@ -35,6 +68,41 @@ export default {
},
created () { },
mounted () {
let query = this.$route.query
this.formData = query.formData
// this.formData = {
// address: "113123123",
// buildId: "1494482424728395778",
// buildName: "",
// customerId: "45687aa479955f9d06204d415238f7cc",
// homeId: "other",
// homeName: "3123123",
// houseHolderName: "",
// houseType: "1",
// memberList: [
// {
// customerId: "45687aa479955f9d06204d415238f7cc",
// domicilePlace: "23123",
// heSuanCount: "2",
// idNum: "312312",
// mobile: "15111111111",
// name: "",
// },
// {
// customerId: "45687aa479955f9d06204d415238f7cc",
// domicilePlace: "123123",
// heSuanCount: null,
// idNum: "",
// mobile: "3123123123",
// name: "",
// }
// ]
// }
console.log(this.formData)
},

Loading…
Cancel
Save