4 changed files with 207 additions and 74 deletions
-
187src/components/home/EditPhoto/index.vue
-
63src/components/home/Photo/index.vue
-
1src/layouts/default.vue
-
30src/views/taskLog/index.vue
@ -0,0 +1,187 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
import { getPhoto, savePhoto } from 'apis/home' |
||||
|
import { getOreList } from 'apis/ore' |
||||
|
import { FtMessage } from 'libs/message' |
||||
|
import { onMounted, ref } from 'vue' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
id: { |
||||
|
type: Number, |
||||
|
default: 0, |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
const emits = defineEmits(['ok', 'cancel']) |
||||
|
|
||||
|
const oreList = ref<Ore.OreItem[]>([]) |
||||
|
onMounted(async () => { |
||||
|
oreList.value = (await getOreList()).list |
||||
|
form.value = await getPhoto(props.id) |
||||
|
form.value.problem.split(',').forEach((item) => { |
||||
|
activeTube.value[Number(item) - 1] = true |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
const form = ref<any>({ |
||||
|
problemList: [], |
||||
|
}) |
||||
|
const formRef = ref() |
||||
|
|
||||
|
const rules = { |
||||
|
oreId: [ |
||||
|
{ required: true, message: '请选择矿石', trigger: 'change' }, |
||||
|
], |
||||
|
} |
||||
|
|
||||
|
const okHandle = async () => { |
||||
|
try { |
||||
|
const valid = await formRef.value.validate() |
||||
|
if (!valid) { |
||||
|
return |
||||
|
} |
||||
|
const params = { |
||||
|
...form.value, |
||||
|
problem: form.value.problemList.join(','), |
||||
|
} |
||||
|
await savePhoto(params) |
||||
|
FtMessage.success('保存成功') |
||||
|
emits('ok') |
||||
|
} |
||||
|
catch (e) { |
||||
|
console.log(e) |
||||
|
} |
||||
|
} |
||||
|
const cancel = () => { |
||||
|
emits('cancel') |
||||
|
} |
||||
|
|
||||
|
const mousedownHandle = async (e: Event) => { |
||||
|
let event |
||||
|
if ('touches' in e) { |
||||
|
event = (e.touches as TouchList)[0] |
||||
|
} |
||||
|
else { |
||||
|
event = e |
||||
|
} |
||||
|
if (event.target!.classList!.contains('tube-inner')) { |
||||
|
const num = event.target!.getAttribute('index') |
||||
|
activeTube.value[Number(num) - 1] = !activeTube.value[Number(num) - 1] |
||||
|
form.value.problemList = activeTube.value.map((item, index) => index + 1).filter(item => activeTube.value[item - 1]) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const activeTube = ref(Array.from({ length: 16 }).fill(false)) |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<FtDialog visible title="保存照片" width="40%" :ok-handle="okHandle" @cancel="cancel"> |
||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="auto"> |
||||
|
<el-form-item label="问题试管"> |
||||
|
<div class="tube-box"> |
||||
|
<div class="tube-item" @click.prevent="mousedownHandle" @touch.prevent="mousedownHandle"> |
||||
|
<span v-for="item in 16" :key="item" class="tube-inner" :class="{ 'tube-inner-active': activeTube[item - 1] }" :index="item" /> |
||||
|
</div> |
||||
|
<el-image |
||||
|
:src="form.url" |
||||
|
:zoom-rate="1.2" |
||||
|
:max-scale="7" |
||||
|
:min-scale="0.2" |
||||
|
:preview-src-list="[form.url]" |
||||
|
fit="contain" |
||||
|
> |
||||
|
<template #error> |
||||
|
<div class="image-slot"> |
||||
|
<el-icon><Picture /></el-icon> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-image> |
||||
|
</div> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="选择矿石" prop="oreId"> |
||||
|
<el-select v-model="form.oreId" placeholder="请选择矿石"> |
||||
|
<el-option v-for="item in oreList" :key="item.id" :label="item.oresName" :value="item.id" /> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="备注" prop="remarks"> |
||||
|
<el-input v-model="form.remarks" type="textarea" placeholder="请输入备注"> |
||||
|
<template #append> |
||||
|
mL |
||||
|
</template> |
||||
|
</el-input> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</FtDialog> |
||||
|
</template> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.el-tag { |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
.el-row { |
||||
|
height: 320px; |
||||
|
.el-col { |
||||
|
height: 100%; |
||||
|
overflow: auto; |
||||
|
:deep(.el-tag) { |
||||
|
width: 100%; |
||||
|
margin-bottom: 5px; |
||||
|
.el-tag__content { |
||||
|
display: flex; |
||||
|
width: 100%; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.tube-box { |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
.el-image { |
||||
|
width: 50%; |
||||
|
height: 140px; |
||||
|
} |
||||
|
.tube-item { |
||||
|
padding: 5px; |
||||
|
background: #384D5D; |
||||
|
border-radius: 10px; |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(4, 1fr); |
||||
|
grid-template-rows: repeat(4, 1fr); |
||||
|
grid-gap: 5px; |
||||
|
position: relative; |
||||
|
.tube-disable { |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
background: rgba(255,255,255,0.9); |
||||
|
border-radius: 9px; |
||||
|
} |
||||
|
.tube-inner { |
||||
|
display: inline-block; |
||||
|
width: 25px; |
||||
|
height: 25px; |
||||
|
border-radius: 50%; |
||||
|
background: #fff; |
||||
|
margin: 2px; |
||||
|
transition: background 0.5s; |
||||
|
} |
||||
|
.tube-inner-active { |
||||
|
background: #26D574; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.image-slot { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background: var(--el-fill-color-light); |
||||
|
color: var(--el-text-color-secondary); |
||||
|
font-size: 30px; |
||||
|
} |
||||
|
</style> |
@ -1,63 +0,0 @@ |
|||||
<script setup lang="ts"> |
|
||||
import { getPhoto } from 'apis/home' |
|
||||
import FtButton from 'components/common/FTButton/index.vue' |
|
||||
import { onMounted, ref } from 'vue' |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
id: { |
|
||||
type: Number, |
|
||||
default: 0, |
|
||||
}, |
|
||||
}) |
|
||||
|
|
||||
const emits = defineEmits(['cancel']) |
|
||||
|
|
||||
const data = ref<any>({}) |
|
||||
onMounted(async () => { |
|
||||
data.value = await getPhoto(props.id) |
|
||||
}) |
|
||||
const cancel = () => { |
|
||||
emits('cancel') |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<template> |
|
||||
<FtDialog visible title="查看照片" width="40%"> |
|
||||
<el-image |
|
||||
:src="data.url" |
|
||||
:zoom-rate="1.2" |
|
||||
:max-scale="7" |
|
||||
:min-scale="0.2" |
|
||||
:preview-src-list="[data.url]" |
|
||||
fit="contain" |
|
||||
> |
|
||||
<template #error> |
|
||||
<div class="image-slot"> |
|
||||
<el-icon><Picture /></el-icon> |
|
||||
</div> |
|
||||
</template> |
|
||||
</el-image> |
|
||||
<template #footer> |
|
||||
<FtButton @click="cancel"> |
|
||||
关闭 |
|
||||
</FtButton> |
|
||||
</template> |
|
||||
</FtDialog> |
|
||||
</template> |
|
||||
|
|
||||
<style scoped lang="scss"> |
|
||||
.el-image { |
|
||||
width: 100%; |
|
||||
height: 200px; |
|
||||
} |
|
||||
.image-slot { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
background: var(--el-fill-color-light); |
|
||||
color: var(--el-text-color-secondary); |
|
||||
font-size: 30px; |
|
||||
} |
|
||||
</style> |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue