优化随手拍列表

This commit is contained in:
BianLzhaoMin 2025-06-23 17:35:55 +08:00
parent e8fa89e0fc
commit 56229baa5c
5 changed files with 390 additions and 131 deletions

View File

@ -5,7 +5,7 @@ export function getMySnapshotList(data) {
return request({
url: '/project/snap/getMySnapshotList',
method: 'get',
params: data
params: data,
})
}
//转违章或者转隐患
@ -13,7 +13,7 @@ export function updateSnapshotStatus(data) {
return request({
url: '/project/snap/updateSnapshotStatus',
method: 'post',
data: data
data: data,
})
}
//删除随手拍
@ -21,7 +21,7 @@ export function delSnapshot(data) {
return request({
url: '/project/snap/delSnapshot',
method: 'post',
data: data
data: data,
})
}
//更新随手拍
@ -32,7 +32,7 @@ export function updateSnapshot(data) {
headers: {
'Content-Type': 'multipart/form-data',
},
data
data,
})
}
@ -41,17 +41,32 @@ export function updateAuditStatus(data) {
return request({
url: '/project/snap/updateAuditStatus',
method: 'post',
data: data
data: data,
})
}
// 获取随手拍列表
export function getSnapshotList(data) {
return request({
url: '/project/snap/getSnapshotList',
method: 'get',
params: data
params: data,
})
}
// 修改随手拍
export function updateSnapshotApi(data) {
return request({
url: '/app/snapshot/addSnapshotForm',
method: 'post',
data,
})
}
// 获取工程下拉选
export function getProOptionsApi(data = {}) {
return request({
url: '/system/select/getProOptions',
method: 'post',
data,
})
}
@ -62,7 +77,7 @@ export function transferViolation(data) {
headers: {
'Content-Type': 'multipart/form-data',
},
data: data
data: data,
})
}
export function transferHiddenDanger(data) {
@ -72,6 +87,6 @@ export function transferHiddenDanger(data) {
headers: {
'Content-Type': 'multipart/form-data',
},
data: data
data: data,
})
}

View File

@ -11,26 +11,25 @@
style="display: none"
ref="upload"
v-if="this.type == 'url'"
>
</el-upload>
></el-upload>
<div class="editor" ref="editor" :style="styles"></div>
</div>
</template>
<script>
import Quill from "quill";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import { getToken } from "@/utils/auth";
import Quill from 'quill'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { getToken } from '@/utils/auth'
export default {
name: "Editor",
name: 'Editor',
props: {
/* 编辑器的内容 */
value: {
type: String,
default: "",
default: '',
},
/* 高度 */
height: {
@ -55,60 +54,60 @@ export default {
/* 类型base64格式、url格式 */
type: {
type: String,
default: "url",
}
default: 'url',
},
},
data() {
return {
uploadUrl: process.env.VUE_APP_BASE_API + "/file/upload", //
uploadUrl: process.env.VUE_APP_BASE_API + '/file/upload', //
headers: {
Authorization: "Bearer " + getToken()
Authorization: 'Bearer ' + getToken(),
},
Quill: null,
currentValue: "",
currentValue: '',
options: {
theme: "snow",
theme: 'snow',
bounds: document.body,
debug: "warn",
debug: 'warn',
modules: {
//
toolbar: [
["bold", "italic", "underline", "strike"], // 线 线
["blockquote", "code-block"], //
[{ list: "ordered" }, { list: "bullet" }], //
[{ indent: "-1" }, { indent: "+1" }], //
[{ size: ["small", false, "large", "huge"] }], //
['bold', 'italic', 'underline', 'strike'], // 线 线
['blockquote', 'code-block'], //
[{ list: 'ordered' }, { list: 'bullet' }], //
[{ indent: '-1' }, { indent: '+1' }], //
[{ size: ['small', false, 'large', 'huge'] }], //
[{ header: [1, 2, 3, 4, 5, 6, false] }], //
[{ color: [] }, { background: [] }], //
[{ align: [] }], //
["clean"], //
["link", "image", "video"] //
['clean'], //
['link', 'image', 'video'], //
],
},
placeholder: "请输入内容",
placeholder: '请输入内容',
readOnly: this.readOnly,
},
};
}
},
computed: {
styles() {
let style = {};
let style = {}
if (this.minHeight) {
style.minHeight = `${this.minHeight}px`;
style.minHeight = `${this.minHeight}px`
}
if (this.height) {
style.height = `${this.height}px`;
style.height = `${this.height}px`
}
return style;
return style
},
},
watch: {
value: {
handler(val) {
if (val !== this.currentValue) {
this.currentValue = val === null ? "" : val;
this.currentValue = val === null ? '' : val
if (this.Quill) {
this.Quill.pasteHTML(this.currentValue);
this.Quill.pasteHTML(this.currentValue)
}
}
},
@ -116,159 +115,160 @@ export default {
},
},
mounted() {
this.init();
this.init()
},
beforeDestroy() {
this.Quill = null;
this.Quill = null
},
methods: {
init() {
const editor = this.$refs.editor;
this.Quill = new Quill(editor, this.options);
const editor = this.$refs.editor
this.Quill = new Quill(editor, this.options)
//
if (this.type == 'url') {
let toolbar = this.Quill.getModule("toolbar");
toolbar.addHandler("image", (value) => {
let toolbar = this.Quill.getModule('toolbar')
toolbar.addHandler('image', value => {
if (value) {
this.$refs.upload.$children[0].$refs.input.click();
this.$refs.upload.$children[0].$refs.input.click()
} else {
this.quill.format("image", false);
this.quill.format('image', false)
}
});
})
}
this.Quill.pasteHTML(this.currentValue);
this.Quill.on("text-change", (delta, oldDelta, source) => {
const html = this.$refs.editor.children[0].innerHTML;
const text = this.Quill.getText();
const quill = this.Quill;
this.currentValue = html;
this.$emit("input", html);
this.$emit("on-change", { html, text, quill });
});
this.Quill.on("text-change", (delta, oldDelta, source) => {
this.$emit("on-text-change", delta, oldDelta, source);
});
this.Quill.on("selection-change", (range, oldRange, source) => {
this.$emit("on-selection-change", range, oldRange, source);
});
this.Quill.on("editor-change", (eventName, ...args) => {
this.$emit("on-editor-change", eventName, ...args);
});
this.Quill.pasteHTML(this.currentValue)
this.Quill.on('text-change', (delta, oldDelta, source) => {
const html = this.$refs.editor.children[0].innerHTML
const text = this.Quill.getText()
const quill = this.Quill
this.currentValue = html
this.$emit('input', html)
this.$emit('on-change', { html, text, quill })
})
this.Quill.on('text-change', (delta, oldDelta, source) => {
this.$emit('on-text-change', delta, oldDelta, source)
})
this.Quill.on('selection-change', (range, oldRange, source) => {
this.$emit('on-selection-change', range, oldRange, source)
})
this.Quill.on('editor-change', (eventName, ...args) => {
this.$emit('on-editor-change', eventName, ...args)
})
},
//
handleBeforeUpload(file) {
const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
const isJPG = type.includes(file.type);
const type = ['image/jpeg', 'image/jpg', 'image/png', 'image/svg']
const isJPG = type.includes(file.type)
//
if (!isJPG) {
this.$message.error(`图片格式错误!`);
return false;
this.$message.error(`图片格式错误!`)
return false
}
//
if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize;
const isLt = file.size / 1024 / 1024 < this.fileSize
if (!isLt) {
this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
return false;
this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`)
return false
}
}
return true;
return true
},
handleUploadSuccess(res, file) {
//
if (res.code == 200) {
//
let quill = this.Quill;
let quill = this.Quill
//
let length = quill.getSelection().index;
let length = quill.getSelection().index
// res.url
quill.insertEmbed(length, "image", res.data.url);
quill.insertEmbed(length, 'image', res.data.url)
//
quill.setSelection(length + 1);
quill.setSelection(length + 1)
} else {
this.$message.error("图片插入失败");
this.$message.error('图片插入失败')
}
},
handleUploadError() {
this.$message.error("图片插入失败");
this.$message.error('图片插入失败')
},
},
};
}
</script>
<style>
.editor, .ql-toolbar {
.editor,
.ql-toolbar {
white-space: pre-wrap !important;
line-height: normal !important;
}
.quill-img {
display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
content: "请输入链接地址:";
.ql-snow .ql-tooltip[data-mode='link']::before {
content: '请输入链接地址:';
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
border-right: 0px;
content: "保存";
content: '保存';
padding-right: 0px;
}
.ql-snow .ql-tooltip[data-mode="video"]::before {
content: "请输入视频地址:";
.ql-snow .ql-tooltip[data-mode='video']::before {
content: '请输入视频地址:';
}
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: "14px";
content: '14px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
content: "10px";
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='small']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='small']::before {
content: '10px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
content: "18px";
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='large']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='large']::before {
content: '18px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
content: "32px";
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='huge']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='huge']::before {
content: '32px';
}
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
content: "文本";
content: '文本';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
content: "标题1";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='1']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='1']::before {
content: '标题1';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
content: "标题2";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='2']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='2']::before {
content: '标题2';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
content: "标题3";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='3']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='3']::before {
content: '标题3';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
content: "标题4";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='4']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='4']::before {
content: '标题4';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
content: "标题5";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='5']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='5']::before {
content: '标题5';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
content: "标题6";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='6']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='6']::before {
content: '标题6';
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: "标准字体";
content: '标准字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
content: "衬线字体";
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='serif']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before {
content: '衬线字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
content: "等宽字体";
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='monospace']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='monospace']::before {
content: '等宽字体';
}
</style>

View File

@ -194,6 +194,7 @@ export default {
auditReason: {
type: Array,
default: [],
required: false,
},
showType: Number, // 1 2
isExamine: false, // true false

View File

@ -6,12 +6,12 @@ const cbc_iv = CryptoJS.enc.Utf8.parse('1234567812345678')
* 默认参数需要加密
* @type {boolean}
*/
const jia_mi = false
const jia_mi = true
/**
* 默认后台会自动加密
* @type {boolean}
*/
const jie_mi = false
const jie_mi = true
/**
* 加密
* @param word

View File

@ -57,6 +57,12 @@
</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template v-slot="scope">
<el-button type="text" @click="onHandleEditSnapshot(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
@ -83,12 +89,77 @@
</div>
</el-dialog>
</el-container>
<!-- 编辑弹框 -->
<el-dialog
title="编辑随手拍"
width="60%"
:visible.sync="editOpenVisible"
v-if="editOpenVisible"
:before-close="() => (editOpenVisible = false)"
>
<el-form
ref="editPhotoForm"
label-width="100px"
label-position="left"
:model="editPhotoForm"
:rules="editPhotoFormRules"
>
<el-form-item label="工程名称" prop="proId">
<!-- <el-input v-model="editPhotoForm.proName" placeholder="请输入工程名称" maxlength="30" show-word-limit /> -->
<el-select
clearable
style="width: 100%"
placeholder="请选择工程名称"
@change="handleProIdChange"
v-model="editPhotoForm.proId"
>
<el-option v-for="item in proOptionsList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="问题描述" prop="description">
<el-input
:rows="5"
type="textarea"
placeholder="请输入问题描述"
maxlength="200"
show-word-limit
v-model="editPhotoForm.description"
:autosize="{ minRows: 2, maxRows: 6 }"
/>
</el-form-item>
<el-form-item label="照片" prop="photoList">
<el-upload
:headers="headers"
:action="uploadUrl"
list-type="picture-card"
:on-remove="handleRemove"
:on-success="handleSuccess"
:before-upload="handleBeforeUpload"
:file-list="editPhotoForm.photoList"
:on-preview="handlePictureCardPreview"
>
<i class="el-icon-plus"></i>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleEditSnapshotSave">保存</el-button>
</el-form-item>
</el-form>
</el-dialog>
<el-dialog :visible.sync="imgDialogVisible" width="40%" append-to-body>
<img width="100%" style="max-height: 70vh; object-fit: contain" :src="dialogImageUrl" alt="" />
</el-dialog>
</div>
</template>
<script>
import Treeselect from '@riophae/vue-treeselect'
import { indexContinuous, lookFaceFile } from '@/utils/bonus'
import { getMySnapshotList } from '@/api/snapshot/snapshot'
import { getMySnapshotList, updateSnapshotApi, getProOptionsApi } from '@/api/snapshot/snapshot'
export default {
components: { Treeselect },
@ -123,12 +194,47 @@ export default {
],
lookFaceFile: '',
userId: '',
headers: {
Authorization: 'Bearer ' + this.$store.getters.token,
},
editOpenVisible: false,
imgDialogVisible: false,
dialogImageUrl: '',
uploadUrl: process.env.VUE_APP_BASE_API + '/file/upload',
//
editPhotoForm: {
id: '', // id
proName: '', //
proId: '', // id
description: '', //
photoList: [], //
photoListTemp: [], //
snapshotId: '',
createTime: '',
createUserName: '',
createUserId: '',
status: '',
// photoNum: '',
},
//
editPhotoFormRules: {
proId: [{ required: true, message: '请选择工程名称', trigger: 'change' }],
description: [{ required: true, message: '请输入问题描述', trigger: 'blur' }],
photoList: [{ required: true, message: '请上传照片', trigger: 'change' }],
},
//
fileType: ['jpg', 'jpeg', 'png'],
proOptionsList: [],
}
},
created() {
this.lookFaceFile = lookFaceFile()
this.userId = this.$route.query.snapshotId || ''
this.getList()
this.getProOptionsFun()
},
methods: {
lookFaceFile,
@ -150,6 +256,143 @@ export default {
this.photoList = item.photoList
this.photoOpen = true
},
//
onHandleEditSnapshot(item) {
this.editPhotoForm.proName = item.proName
this.editPhotoForm.proId = item.proId
this.editPhotoForm.description = item.description
this.editPhotoForm.id = item.id
this.editPhotoForm.snapshotId = item.snapshotId
this.editPhotoForm.createTime = item.createTime
this.editPhotoForm.createUserName = item.createUserName
this.editPhotoForm.createUserId = item.createUserId
this.editPhotoForm.status = item.status
// this.editPhotoForm.photoNum = item.photoNum
this.editPhotoForm.photoList = item.photoList.map(item => ({
filePath: item.url,
name: item.fileName,
url: this.lookFaceFile + item.url,
}))
this.editOpenVisible = true
},
//
handleBeforeUpload(file) {
const isFormat = this.fileType.some(e => file.name.endsWith(e))
if (!isFormat) {
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join('、')}格式的文件!`)
return false
}
// //
// const isLt = file.size / 1024 / 1024 < this.fileSize
// if (!isLt) {
// this.$modal.msgError(` ${this.fileSize} MB`)
// return false
// }
// #
const newFileName = file.name.replace(/#/g, '@')
const newFile = new File([file], newFileName, { type: file.type })
// name
Object.defineProperty(file, 'name', {
value: newFileName,
})
return true
},
//
handleSuccess(response, file, fileList) {
if (response.code == 200) {
this.editPhotoForm.photoList.push({
filePath: response.data.url,
url: this.lookFaceFile + response.data.url,
name: response.data.name,
})
console.log(this.editPhotoForm, '-----------上传成功')
//
this.$refs.editPhotoForm.clearValidate('photoList')
}
},
//
handleRemove(file, fileList) {
console.log(file, fileList, '-----------删除')
this.editPhotoForm.photoList = this.editPhotoForm.photoList.filter(item => item.filePath != file.filePath)
},
//
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.imgDialogVisible = true
},
//
handleEditSnapshotSave() {
this.$refs.editPhotoForm.validate(async valid => {
if (valid) {
console.log(this.editPhotoForm, '-----------保存按钮')
const {
proName,
description,
photoList,
id,
snapshotId,
createTime,
createUserName,
createUserId,
status,
proId,
} = this.editPhotoForm
let photoListNew = []
if (photoList.length > 0) {
photoListNew = photoList.map(item => {
return {
filePath: item.filePath,
fileName: item.name,
}
})
}
//
const params = {
proName,
description,
id,
snapshotId,
createTime,
createUserName,
createUserId,
status,
proId,
pageType: 'edit',
photoType: photoListNew,
}
console.log(params, '-----------params')
const res = await updateSnapshotApi(params)
if (res.code == 200) {
this.$modal.msgSuccess('修改成功')
this.editOpenVisible = false
this.getList()
}
}
})
},
//
async getProOptionsFun() {
const res = await getProOptionsApi({})
this.proOptionsList = res.data
},
handleProIdChange(val) {
this.editPhotoForm.proName = this.proOptionsList.find(item => item.value == val)?.label
},
},
}
</script>