Browse Source

fix:打卡上报页面构建

featrue-lingshan
LL 4 months ago
parent
commit
c99773dc75
  1. 395
      src/views/modules/hengAnShield/checkInReport/components/checkInReportDetail.vue
  2. 345
      src/views/modules/hengAnShield/checkInReport/index.vue
  3. 6
      src/views/modules/hengAnShield/inspectionRecord/index.vue
  4. 9
      src/views/modules/plugins/rent/upload-image.vue
  5. 2
      src/views/modules/villageGovernance/revitalize/components/revitalizeDialog.vue

395
src/views/modules/hengAnShield/checkInReport/components/checkInReportDetail.vue

@ -0,0 +1,395 @@
<template>
<el-dialog :visible.sync="visible" :title="title" :close-on-click-modal="false" :close-on-press-escape="false"
width="950px" top="5vh" class="dialog-h" :before-close="handleCancel">
<div class="dialog-h-content scroll-h">
<div class="title">基本信息</div>
<div class="content">
<div class="div_row">
<div class="div_row_td">
<div class="label">
所属组织</div>
<div class="value">1212121</div>
</div>
<div class="div_row_td">
<div class="label">
巡检类型</div>
<div class="value">1212121</div>
</div>
<div class="div_row_td">
<div class="label">
姓名</div>
<div class="value">1212121</div>
</div>
</div>
<div class="div_row">
<div class="div_row_td">
<div class="label">
手机号</div>
<div class="value">1212121</div>
</div>
<div class="div_row_td">
<div class="label">
身份证号</div>
<div class="value">1212121</div>
</div>
</div>
<div class="div_row div_row_content">
<div class="div_row_td">
<div class="label">
上报内容</div>
<div class="value">
<playAudio :theUrl="formData.audioUrl" />
</div>
</div>
</div>
<div class="div_row div_row_img">
<div class="div_row_td">
<div class="label">
上传图片</div>
<div class="value">
<upload-image :defaultFileList="fileList" :isDetail="true" :is-in-preview="false" :limit="1"
@preview="handleImgPreview"></upload-image>
</div>
</div>
</div>
<div class="div_row">
<div class="div_row_td">
<div class="label">
上报时间</div>
<div class="value">1212121</div>
</div>
<div class="div_row_td">
<div class="label">
上报地点</div>
<div class="value">1212121</div>
</div>
</div>
</div>
<div class="title">处理状态</div>
<div class="status">
<div style="display: flex; align-items: center;">
<div style="width: 120px;text-align: right;"><span style="color: #FF5D5C; font-size: 16px;">*</span>处理结果
</div>
<div>
<el-select v-model="formData.status" size="small" placeholder="请选择">
<el-option label="未处理" value="0"></el-option>
<el-option label="已处理" value="1"></el-option>
</el-select>
</div>
</div>
<div style="display: flex; align-items: center; margin-top: 12px;">
<div style="width: 120px;text-align: right;">备注</div>
<div style="width: 500px;">
<el-input v-model="formData.remark" type="textarea" :autosize="{ minRows: 4, maxRows: 4 }"
placeholder="请输入备注"></el-input>
</div>
</div>
</div>
<div class="div_btn">
<el-button size="small" @click="handleCancel" :loading="btnDisable"> </el-button>
<el-button size="small" type="primary" :loading="btnDisable" @click="handleConfirm"> </el-button>
</div>
<!-- 上传图片预览 -->
<el-image-viewer v-if="isShowPics" :on-close="closeViewer" :url-list="[this.fileList[0].fileUrl]" />
</div>
</el-dialog>
</template>
<script>
import _ from 'lodash'
import dayjs from 'dayjs'
import { Loading } from 'element-ui' // Loading
import { requestPost, requestGet } from '@/js/dai/request'
import Tinymce from '@c/tinymce2/index.vue'
import UploadImage from '@/views/modules/plugins/rent/upload-image.vue'
import ElImageViewer from "element-ui/packages/image/src/image-viewer"
import playAudio from '@/views/modules/hengAnShield/inspectionRecord/components/playAudio.vue'
const defaultFormData = {
id: undefined,
title: '',
agencyId: '',
startTime: '',
endTime: '',
audioUrl: 'https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/20260115/83ae2f54ad2d49a0ad7378e7e8f67c60.mp3',
}
let loading //
export default {
name: 'checkInReportDetail',
components: { Tinymce, UploadImage, ElImageViewer, playAudio },
props: {
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: ''
}
},
data() {
return {
formData: _.cloneDeep(defaultFormData),
btnDisable: false,
cascaderAgencyId: [],
organizeOptions: [],
fileList: [{ fileType: '0', fileUrl: 'https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/20260121/89ce2d841ffe454abbed527dd57ec33d.jpg' }],
isShowPics: false
}
},
created() {
this.getOptions()
},
methods: {
//
async getOptions() {
const { data } = await requestPost("/gov/org/customeragency/orgtree", {});
this.organizeOptions = data ? [this.computeOption(data)] : []
},
//
computeOption(opt) {
return {
label: opt.agencyName,
value: opt.agencyId,
type: "agency",
children: [
...this.processDepartmentList(opt.departmentList),
...this.processGridList(opt.gridList),
...this.processSubAgencyList(opt.subAgencyList),
],
};
},
//
processDepartmentList(departmentList) {
return (departmentList || []).map((item) => ({
label: item.deptName,
value: item.deptId,
type: "dept",
typeName: "部门",
}))
},
//
processGridList(gridList) {
return (gridList || []).map((item) => ({
label: item.gridName,
value: item.gridId,
type: "grid",
typeName: "网格",
}))
},
//
processSubAgencyList(subAgencyList) {
return (subAgencyList || []).map((item) => this.computeOption(item))
},
//
async initForm(row) {
if (row && row.id) {
this.startLoading()
let url = `/actual/base/data/clockIn/${row.id}`
const { data, code, msg } = await requestPost(url)
this.formData = data ? data : _.cloneDeep(defaultFormData);
this.formData.audioUrl = 'https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/20260115/83ae2f54ad2d49a0ad7378e7e8f67c60.mp3'
console.log('data======', this.formData)
}
this.endLoading();
},
//
handleOrgChange(val) {
this.formData.agencyId = val[val.length - 1];
this.$refs['ref_form'].validateField('agencyId');
},
async handleConfirm() {
this.$refs['ref_form'].validate(async valid => {
if (valid) {
this.btnDisable = true;
let url = this.formData.id ? '/actual/base/importantTask/update' : '/actual/base/importantTask/save'
this.formData.startTime = dayjs(this.formData.startTime).startOf('day').format("YYYY-MM-DD HH:mm:ss");
this.formData.endTime = dayjs(this.formData.endTime).endOf('day').format("YYYY-MM-DD HH:mm:ss");
this.formData.releaseTime = this.formData.releaseTime || dayjs().format("YYYY-MM-DD HH:mm:ss")
const { data, code, internalMsg } = await requestPost(url, this.formData)
if (code === 0) {
this.$message.success(this.formData.id ? '更新成功' : '新增成功')
this.resetData()
this.$emit('update:visible', false)
this.$emit('success')
} else {
this.$message.error(internalMsg)
}
this.btnDisable = false
}
})
},
//
handleImgPreview(file) {
this.isShowPics = true
},
closeViewer() {
this.isShowPics = false
},
//
handleCancel() {
this.resetData()
this.$emit('update:visible', false)
},
resetData() {
this.formData = _.cloneDeep(defaultFormData)
// this.$refs['ref_form'].resetFields()
this.cascaderAgencyId = []
},
//
startLoading() {
loading = Loading.service({
lock: true, //
text: '正在加载……', //
background: 'rgba(0,0,0,.7)' //
})
},
//
endLoading() {
// clearTimeout(timer);
if (loading) {
loading.close()
}
}
},
computed: {
dataRule() {
return {
title: [
{ required: true, message: '请输入任务名称', trigger: 'blur' }
],
agencyId: [
{ required: true, message: '请选择所属组织', trigger: 'change' }
],
timeRange: [
{
required: true, validator: (rule, value, callback) => {
if (!this.formData.startTime && !this.formData.endTime) {
return callback(new Error('请选择有效期'));
} else if (!this.formData.startTime) {
return callback(new Error('请选择开始时间'));
} else if (!this.formData.endTime) {
return callback(new Error('请选择结束时间'));
} else {
callback();
}
}, trigger: 'change'
}
]
}
},
startTimePickerOptions() {
return {
disabledDate: (time) => {
if (this.formData.endTime) {
return time.getTime() > new Date(this.formData.endTime).getTime();
}
return false;
}
};
},
endTimePickerOptions() {
return {
disabledDate: (time) => {
if (this.formData.startTime) {
return time.getTime() < new Date(this.formData.startTime).getTime();
}
return false;
}
};
}
}
}
</script>
<style lang="scss" scoped>
.title {
margin-top: 20px;
font-size: 16px;
font-weight: 500;
color: #333;
}
.content {
width: 96%;
min-height: 200px;
margin: 10px auto;
border-bottom: 1px solid #EBECEC;
border-right: 1px solid #EBECEC;
.div_row {
width: 100%;
height: 50px;
display: flex;
border-top: 1px solid #EBECEC;
.div_row_td {
display: flex;
align-items: center;
height: 100%;
width: 33%;
.label {
width: 120px;
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
border-left: 1px solid #EBECEC;
border-right: 1px solid #EBECEC;
}
.value {
flex: 1;
height: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
padding-left: 4px;
}
}
&.div_row_content,
&.div_row_img {
height: 80px;
.div_row_td {
width: 100%;
}
}
}
}
.status {
width: 96%;
min-height: 100px;
margin: 10px auto;
}
.div_btn {
width: 100%;
text-align: right;
padding-right: 20px;
}
</style>

345
src/views/modules/hengAnShield/checkInReport/index.vue

@ -0,0 +1,345 @@
<template>
<div class="g-main">
<!-- 打卡上报 -->
<div class="m-search">
<el-form :inline="true" :model="queryParams" ref="ref_searchform" :label-width="'100px'">
<div>
<el-form-item label="所属组织" prop="agencyId">
<el-cascader style="width: 100%;" v-model="cascaderAgencyId" :options="organizeOptions"
:props="{ checkStrictly: true, multiple: false, value: 'value', label: 'label', children: 'children' }"
:show-all-levels="false" @change="handleOrgChange" clearable></el-cascader>
</el-form-item>
<el-form-item label="打卡上报类型" prop="status" :label-width="'140px'">
<el-select class="item_width_1" v-model.trim="queryParams.status" placeholder="全部" clearable>
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model.trim="queryParams.name" class="item_width_1" clearable placeholder="请输入">
</el-input>
</el-form-item>
<el-form-item label="手机号" prop="mobile">
<el-input v-model.trim="queryParams.mobile" class="item_width_1" clearable placeholder="请输入">
</el-input>
</el-form-item>
<el-form-item label="上报时间" prop="timeRange">
<el-date-picker v-model="timeRange" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss"
format="yyyy-MM-dd HH:mm:ss" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间">
</el-date-picker>
</el-form-item>
</div>
<div>
<div style="display: flex; justify-content: flex-end;">
<el-button style="margin-left:10px" class="diy-button--blue" size="small"
@click="handleSearch">查询</el-button>
<el-button style="margin-left:10px" class="diy-button--white" size="small"
@click="resetSearch">重置</el-button>
</div>
</div>
</el-form>
</div>
<div class="m-table">
<!-- <div class="div_btn">
<el-button style="" class="diy-button--add" size="small" @click="handleAdd">新增</el-button>
</div> -->
<el-table class="table" :data="tableData" border :height="tableHeight" v-loading="tableLoading"
style="width: 100%;margin-top:16px">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50" />
<el-table-column prop="partyOrgName" header-align="center" align="center" label="所属组织" />
<el-table-column prop="type" header-align="center" align="center" label="打卡上报类型" :formatter="formatterType" />
<el-table-column prop="userName" header-align="center" align="center" label="上报人" />
<el-table-column prop="mobile" header-align="center" align="center" label="手机" />
<el-table-column prop="content" header-align="center" align="center" label="上报内容" />
<el-table-column prop="coverPic" header-align="center" align="center" label="图片" width="80">
<template slot-scope="{row}">
<el-image :src="row.patrolImage" fit="fill" :preview-src-list="[row.patrolImage]"
style="width: 50px; height: 50px;">
</el-image>
</template>
</el-table-column>
<el-table-column prop="releaseTime" header-align="center" align="center" label="上报时间">
</el-table-column>
<el-table-column label="操作" fixed="right" header-align="center" align="center" class="operate" width="120">
<template slot-scope="scope">
<el-button v-if="scope.row.status === 0" type="text" style="color:#1C6AFD;" size="small" @click="handleDetail(scope.row)">处理</el-button>
<el-button v-else type="text" style="color:#1C6AFD;" size="small" @click="handleDetail(scope.row)">查看</el-button>
<el-button type="text" style="color:#1C6AFD;" size="small" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div>
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="pageNo"
:page-sizes="[10, 20, 50]" :page-size="pageSize" layout="sizes, prev, pager, next, total" :total="total">
</el-pagination>
</div>
</div>
<!-- 新增 || 修改 || 查看弹出框 -->
<check-in-report-detail ref="checkInReportDetail" :visible.sync="dialogVisible" :title="dialogTitle"
@success="getDataList"></check-in-report-detail>
</div>
</template>
<script>
import dayjs from 'dayjs'
import { mapGetters } from 'vuex'
import checkInReportDetail from '@/views/modules/hengAnShield/checkInReport/components/checkInReportDetail'
import { requestPost, requestGet } from "@/js/dai/request";
import { Loading } from 'element-ui'
let loading //
export default {
name: 'revitalizeIndex',
components: {
checkInReportDetail
},
data() {
return {
loading: false,
total: 0,
pageSize: 10,
pageNo: 1,
tableLoading: false,
timeRange: [],
queryParams: {
title: "",
agencyId: "",
startTime: "",
endTime: "",
},
cascaderAgencyId: [],
organizeOptions: [],
tableData: [],
typeList: [
{label: '工作打卡', value: '1'},
{label: '事件打卡', value: '2'},
],
dialogVisible: false,
dialogTitle: '',
}
},
created() {
this.getOptions();
//
this.getDataList();
},
methods: {
onLoadedmetadata(res) {
console.log('loadedmetadata')
console.log(res)
const duration = res.target.duration
console.log('duration', duration)
},
//
async getOptions() {
const { data } = await requestPost("/gov/org/customeragency/orgtree", {});
this.organizeOptions = data ? [this.computeOption(data)] : []
},
//
computeOption(opt) {
return {
label: opt.agencyName,
value: opt.agencyId,
type: "agency",
children: [
...this.processDepartmentList(opt.departmentList),
...this.processGridList(opt.gridList),
...this.processSubAgencyList(opt.subAgencyList),
],
};
},
//
processDepartmentList(departmentList) {
return (departmentList || []).map((item) => ({
label: item.deptName,
value: item.deptId,
type: "dept",
typeName: "部门",
}))
},
//
processGridList(gridList) {
return (gridList || []).map((item) => ({
label: item.gridName,
value: item.gridId,
type: "grid",
typeName: "网格",
}))
},
//
processSubAgencyList(subAgencyList) {
return (subAgencyList || []).map((item) => this.computeOption(item))
},
//
handleOrgChange(val) {
this.queryParams.agencyId = val[val.length - 1];
},
async getDataList() {
const url = "/actual/base/data/clockIn/list";
this.queryParams.startTime = this.timeRange[0]? this.timeRange[0] : '';
this.queryParams.endTime = this.timeRange[1]? this.timeRange[1] : '';
let params = {
pageSize: this.pageSize,
pageNo: this.pageNo,
...this.queryParams,
};
let { data, code, msg } = await requestGet(url, params);
console.log('data===', data)
if (code === 0) {
this.total = data.total
this.tableData = data.list
} else {
this.$message.error(msg)
}
},
handleSearch() {
this.pageNo = 1
this.getDataList()
},
//
handleAdd() {
this.dialogVisible = true
this.dialogTitle = '新增'
this.$nextTick(() => {
this.$refs.checkInReportDetail.initForm()
})
},
//
handleEdit(row) {
this.dialogVisible = true
this.dialogTitle = '编辑'
this.$nextTick(() => {
this.$refs.checkInReportDetail.initForm(row)
})
},
//
handleDetail(row) {
this.dialogVisible = true
this.dialogTitle = '详情'
this.$nextTick(() => {
this.$refs.checkInReportDetail.initForm(row)
})
},
//
async handleDelete(row) {
this.$confirm("确认删除?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(async () => {
const url = "/actual/base/importantTask/delete"
let id = [row.id]
const { data, code, internalMsg } = await requestPost(url, id)
if (code === 0) {
this.$message({
type: "success",
message: "删除成功"
});
this.getDataList()
} else {
this.$message.error(internalMsg)
}
})
.catch(err => {
});
},
//
resetSearch() {
this.timeRange = []
this.queryParams = {
title: "",
status: "",
startTime: "",
endTime: "",
}
this.pageSize = 10
this.pageNo = 1
this.getDataList()
},
handleSizeChange(val) {
this.pageSize = val
this.pageNo = 1
this.getDataList()
},
handleCurrentChange(val) {
this.pageNo = val
this.getDataList()
},
//
formatterType(row) {
if (row.type) {
let obj = this.typeList.find(item => item.value === row.type);
return obj && obj.label || ''
}
},
//
startLoading() {
loading = Loading.service({
lock: true, //
text: '正在加载……', //
background: 'rgba(0,0,0,.7)' //
})
},
//
endLoading() {
// clearTimeout(timer);
if (loading) {
loading.close()
}
}
},
computed: {
tableHeight() {
return this.$store.state.inIframe ? this.clientHeight - 430 + this.iframeHeight : this.clientHeight - 430
},
...mapGetters(['clientHeight', 'iframeHeight'])
}
}
</script>
<style lang="scss" scoped>
.g-main {
width: 100%;
}
.m-search {
background: #ffffff;
border-radius: 4px;
padding: 24px 10px 10px;
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.1);
margin: 20px 7px 7px;
}
.m-table {
background: #ffffff;
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.1);
border-radius: 4px;
margin-top: 15px;
padding: 24px 16px 10px;
margin: 16px 7px 7px;
}
</style>

6
src/views/modules/hengAnShield/inspectionRecord/index.vue

@ -11,7 +11,7 @@
</el-form-item>
<el-form-item label="巡检类型" prop="status">
<el-select class="item_width_1" v-model.trim="queryParams.status" size="small" placeholder="全部" clearable>
<el-select class="item_width_1" v-model.trim="queryParams.status" placeholder="全部" clearable>
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
@ -45,9 +45,9 @@
</div>
<div class="m-table">
<div class="div_btn">
<!-- <div class="div_btn">
<el-button style="" class="diy-button--add" size="small" @click="handleAdd">新增</el-button>
</div>
</div> -->
<el-table class="table" :data="tableData" border :height="tableHeight" v-loading="tableLoading"
style="width: 100%;margin-top:16px">

9
src/views/modules/plugins/rent/upload-image.vue

@ -1,5 +1,5 @@
<template>
<div class="upload-image">
<div class="upload-image" :class="isDetail? 'isDetail' : ''">
<el-upload :headers="$getElUploadHeaders()" list-type="picture-card"
:action="uploadUrl"
:data="{ customerId: customerId }"
@ -43,6 +43,10 @@ export default {
defaultFileList: {
type: Array
},
isDetail: {
type: Boolean,
default: false
},
isInPreview: {
type: Boolean,
default: true
@ -135,4 +139,7 @@ export default {
width: 60px;
height: 60px;
}
.isDetail ::v-deep .el-upload--picture-card {
display: none;
}
</style>

2
src/views/modules/villageGovernance/revitalize/components/revitalizeDialog.vue

@ -23,7 +23,7 @@
<el-form-item label="上传照片" label-width="150px" prop="coverPic">
<div class="item_width_1">
<upload-image :defaultFileList="fileList" :is-in-preview="false" :limit="1" @change="onChangeFileList"
<upload-image :defaultFileList="fileList" :isDetail="title.includes('详情')" :is-in-preview="false" :limit="1" @change="onChangeFileList"
@file-removed="removedImg" @preview="handleImgPreview"></upload-image>
</div>
</el-form-item>

Loading…
Cancel
Save