609 lines
20 KiB
Vue
609 lines
20 KiB
Vue
<template>
|
||
<div class="custom-page">
|
||
<avue-crud
|
||
ref="crudRef"
|
||
v-model:page="pageData"
|
||
:data="crudData"
|
||
:option="crudOptions"
|
||
:table-loading="loading"
|
||
@refresh-change="handleRefresh"
|
||
@current-change="handleCurrentChange"
|
||
@size-change="handleSizeChange"
|
||
>
|
||
<template #menu-left>
|
||
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
|
||
<el-button type="success" icon="download" @click="handleExport">导出</el-button>
|
||
</template>
|
||
<template #menu="scope">
|
||
<custom-table-operate :actions="getActions(scope.row)" :data="scope" />
|
||
</template>
|
||
</avue-crud>
|
||
|
||
<el-dialog :key="dialogTitle" v-model="visible" :title="dialogTitle" width="60%" align-center :draggable="true">
|
||
<p class="form-group">任务信息</p>
|
||
<el-form :model="taskForm" :disabled="isReadonlyInfo" label-width="100px">
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="任务编号" prop="taskCode">
|
||
<el-input v-model="taskForm.taskCode" placeholder="请输入任务编号" />
|
||
</el-form-item>
|
||
<el-form-item label="任务成员" prop="taskUserIds">
|
||
<!-- /land-resource/grid-member/current-user -->
|
||
<url-select
|
||
v-model="taskForm.taskUserIds"
|
||
url="/land-resource/grid-member/current-user"
|
||
placeholder="请选择任务成员"
|
||
multiple="true"
|
||
label-key="memberName"
|
||
value-key="id"
|
||
:response-parser="(res) => res.data.memberList"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="注意事项" prop="notes">
|
||
<el-input v-model="taskForm.notes" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" placeholder="请输入注意事项" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="任务名称" prop="taskName">
|
||
<el-input v-model="taskForm.taskName" placeholder="请输入任务名称" />
|
||
</el-form-item>
|
||
<el-form-item label="巡查类型" prop="inspectionTypeCode">
|
||
<url-select
|
||
v-model="taskForm.inspectionTypeCode"
|
||
url="/system/dict/data/type/land_res_patrol_type"
|
||
placeholder="请选择巡查类型"
|
||
label-key="dictLabel"
|
||
value-key="dictValue"
|
||
:response-parser="(res) => res.data"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="巡查对象" prop="inspectionTarget">
|
||
<el-input v-model="taskForm.inspectionTarget" placeholder="请输入巡查对象" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<!-- 巡查信息登记,只有进行过结果登记的才显示 -->
|
||
<template v-if="dialogTitle !== '查看' && dialogTitle !== '详情' && dialogTitle !== '新增' && dialogTitle !== '编辑'">
|
||
<p class="form-group">巡查信息登记</p>
|
||
|
||
<!-- 循环渲染多个表单 -->
|
||
<div v-for="(form, index) in illegalForms" :key="index" class="form-container">
|
||
<div class="form-header">
|
||
<span>记录 #{{ index + 1 }}</span>
|
||
<el-button v-if="!isReadonlyRegist" type="danger" icon="el-icon-delete" circle size="mini" @click="handleRemoveForm(index)" />
|
||
</div>
|
||
|
||
<el-form :model="form" :disabled="isReadonlyRegist" label-width="100px" class="form-item">
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<!-- 选择地块 -->
|
||
<el-form-item label="选择地块" prop="landId">
|
||
<url-select
|
||
v-model="form.landId"
|
||
url="/land-resource/landManage/page"
|
||
placeholder="请选择地块"
|
||
label-key="landName"
|
||
value-key="id"
|
||
:params="{ current: 1, size: 999 }"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="是否违法" prop="illegalFlag">
|
||
<el-radio-group v-model="form.illegalFlag">
|
||
<el-radio value="1">是</el-radio>
|
||
<el-radio value="0">否</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<!-- 违法时间 -->
|
||
<el-form-item v-if="form.illegalFlag === '1'" label="违法时间" prop="illegalDate">
|
||
<el-date-picker
|
||
v-model="form.illegalDate"
|
||
type="datetime"
|
||
placeholder="选择违法时间"
|
||
format="YYYY年MM月DD日"
|
||
value-format="YYYY-MM-DD"
|
||
:disabled="isReadonlyRegist || form.illegalFlag === 0"
|
||
/>
|
||
</el-form-item>
|
||
<!-- 违法图片 -->
|
||
<el-form-item v-if="form.illegalFlag === '1'" label="违法图片" prop="illegalImages">
|
||
<file-uploader v-model="form.illegalImages" :limit="1" :readonly="isReadonlyRegist || form.illegalFlag === 0" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col v-if="form.illegalFlag === '1'" :span="12">
|
||
<el-form-item label="违法类型" prop="illegalType">
|
||
<url-select
|
||
v-model="form.illegalTypeCode"
|
||
url="/system/dict/data/type/land_inspection_illegal_type"
|
||
placeholder="请选择违法类型"
|
||
label-key="dictLabel"
|
||
value-key="dictValue"
|
||
:response-parser="(res) => res.data"
|
||
:disabled="isReadonlyRegist || form.illegalFlag === 0"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item v-if="form.illegalFlag === '1'" label="违法行为描述" prop="desc">
|
||
<el-input
|
||
v-model="form.desc"
|
||
:autosize="{ minRows: 2, maxRows: 6 }"
|
||
type="textarea"
|
||
placeholder="请输入违法行为描述"
|
||
:disabled="isReadonlyRegist || form.illegalFlag === 0"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
</div>
|
||
|
||
<div v-if="!isReadonlyRegist" class="form-footer">
|
||
<el-button type="primary" @click="handleAddForm"> 添加记录 </el-button>
|
||
</div>
|
||
</template>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<!-- <el-button @click="infoCancel">取消</el-button> -->
|
||
<el-button type="primary" @click="handleSubmit()"> 确认 </el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive, watch, onMounted, computed, nextTick } from 'vue';
|
||
import { CRUD_OPTIONS } from '@/config';
|
||
import { ElMessage } from 'element-plus';
|
||
import { useActionPermissions } from '@/hooks/useActionPermissions';
|
||
import { useUserStore } from '@/store/modules/user';
|
||
import {
|
||
createLandInspection,
|
||
deleteLandInspection,
|
||
updateLandInspection,
|
||
updateLandInspectionStatus,
|
||
getLandInspectionDetail,
|
||
fetchLandInspectionList,
|
||
exportLandInspection,
|
||
createInspectionResult,
|
||
createInspectionResultBatch,
|
||
deleteInspectionResult,
|
||
getInspectionResultDetail,
|
||
} from '@/apis/landResourceManagement/landInspection/index';
|
||
|
||
const dialogTitle = ref('新增');
|
||
const visible = ref(false);
|
||
const isReadonlyInfo = ref(false);
|
||
const isReadonlyRegist = ref(false);
|
||
const UserStore = useUserStore();
|
||
const user = UserStore.getUserInfo();
|
||
console.log('admin 属性:', user.admin);
|
||
|
||
const pageData = ref({
|
||
currentPage: 1,
|
||
pageSize: 10,
|
||
total: 0,
|
||
});
|
||
const searchForm = ref({
|
||
taskCode: '',
|
||
taskName: '',
|
||
userId: '',
|
||
inspectionTypeCode: '',
|
||
gridId: '',
|
||
});
|
||
|
||
const taskForm = ref({
|
||
id: '', // 任务ID
|
||
taskCode: '', // 任务编号
|
||
taskName: '', // 任务名称
|
||
taskUserIds: [], // 任务成员ID列表
|
||
taskMembers: '', // 任务成员
|
||
inspectionTypeCode: '', // 巡查类型代码
|
||
inspectionType: '', // 巡查类型
|
||
inspectionTarget: '', // 巡查对象
|
||
inspectionStatus: '', // 巡查状态
|
||
notes: '', // 注意事项
|
||
inspectionResults: [], // 巡查结果列表
|
||
});
|
||
const illegalForm = ref({
|
||
id: '', // 登记ID
|
||
inspectionId: '', // 任务ID
|
||
inspectionTaskName: '', // 巡查任务名称
|
||
landId: '', // 地块ID
|
||
landName: '', // 地块名称
|
||
illegalFlag: 0, // 是否违法
|
||
illegalDate: '', // 违法时间
|
||
illegalTypeCode: '', // 违法类型代码
|
||
illegalTypeName: '', // 违法类型名称
|
||
desc: '', // 违法描述
|
||
img: '', // 违法图片
|
||
status: '', // 状态
|
||
});
|
||
const illegalForms = ref([{ ...illegalForm.value }]);
|
||
const crudData = ref([]);
|
||
const loading = ref(false);
|
||
const crudOptions = reactive({
|
||
...CRUD_OPTIONS,
|
||
addBtn: false,
|
||
searchBtn: false,
|
||
emptyBtn: false,
|
||
column: [
|
||
{ label: '任务编号', prop: 'taskCode' },
|
||
{ label: '任务名称', prop: 'taskName' },
|
||
{ label: '任务成员', prop: 'taskMembers' },
|
||
{ label: '巡查类型', prop: 'inspectionType' },
|
||
{ label: '巡查对象', prop: 'inspectionTarget' },
|
||
{ label: '注意事项', prop: 'notes' },
|
||
{ label: '是否违法', prop: 'isIllegal' },
|
||
{ label: '状态', prop: 'inspectionStatusName' },
|
||
],
|
||
actions: [
|
||
{
|
||
name: '查看',
|
||
icon: 'view',
|
||
event: ({ row }) => handleView(row.id),
|
||
},
|
||
{
|
||
name: '编辑',
|
||
icon: 'edit',
|
||
event: ({ row }) => handleEdit(row.id),
|
||
},
|
||
{
|
||
type: 'danger',
|
||
name: '删除',
|
||
icon: 'delete',
|
||
event: ({ row }) => handleDelete(row.id),
|
||
},
|
||
// 结果登记
|
||
{
|
||
name: '结果登记',
|
||
icon: 'result',
|
||
event: ({ row }) => handleResult(row.id),
|
||
},
|
||
// 收回任务
|
||
{
|
||
name: '收回任务',
|
||
icon: 'back',
|
||
event: ({ row }) => handleBack(row.id),
|
||
},
|
||
// 发布任务
|
||
{
|
||
name: '发布任务',
|
||
icon: 'publish',
|
||
event: ({ row }) => handlePublish(row.id),
|
||
},
|
||
// 重新发布
|
||
{
|
||
name: '重新发布',
|
||
icon: 're-publish',
|
||
event: ({ row }) => handleRePublish(row.id),
|
||
},
|
||
// 查看登记结果
|
||
{
|
||
name: '查看登记结果',
|
||
icon: 'view-result',
|
||
event: ({ row }) => handleViewResult(row),
|
||
},
|
||
],
|
||
});
|
||
|
||
onMounted(() => {
|
||
getData();
|
||
});
|
||
const getData = async () => {
|
||
loading.value = true;
|
||
try {
|
||
const response = await fetchLandInspectionList({
|
||
current: pageData.value.currentPage,
|
||
size: pageData.value.pageSize,
|
||
...searchForm.value,
|
||
});
|
||
crudData.value = response.data.records;
|
||
pageData.value.total = response.data.total;
|
||
pageData.value.currentPage = response.data.current;
|
||
pageData.value.pageSize = response.data.size;
|
||
} catch (error) {
|
||
ElMessage.error('加载数据失败');
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
};
|
||
const handleAdd = () => {
|
||
isReadonlyInfo.value = false;
|
||
// resetForm();
|
||
dialogTitle.value = '新增';
|
||
visible.value = true;
|
||
};
|
||
const handleEdit = async (id) => {
|
||
console.log('编辑行:', id);
|
||
isReadonlyInfo.value = false;
|
||
const response = await getLandInspectionDetail(id);
|
||
taskForm.value = response.data;
|
||
// 处理返回的任务成员数组inspectionUsers[]数据为选择器需要的id数组taskUserIds[]
|
||
if (taskForm.value.inspectionUsers && Array.isArray(taskForm.value.inspectionUsers)) {
|
||
taskForm.value.taskUserIds = taskForm.value.inspectionUsers.map((user) => user.userId);
|
||
} else {
|
||
taskForm.value.taskUserIds = [];
|
||
}
|
||
dialogTitle.value = '编辑';
|
||
visible.value = true;
|
||
};
|
||
const handleView = async (id) => {
|
||
console.log('查看行:', id);
|
||
const response = await getLandInspectionDetail(id);
|
||
taskForm.value = response.data;
|
||
const arr = response.data.inspectionResults;
|
||
illegalForms.value = arr ? arr : [];
|
||
illegalForms.value.forEach((item) => {
|
||
// 如果后端只给了一个 img 字符串
|
||
if (item.img) {
|
||
// 直接包成数组
|
||
item.illegalImages = [item.img];
|
||
} else {
|
||
// 没图时给空数组
|
||
item.illegalImages = [];
|
||
}
|
||
});
|
||
isReadonlyInfo.value = true;
|
||
if (taskForm.value.inspectionUsers && Array.isArray(taskForm.value.inspectionUsers)) {
|
||
taskForm.value.taskUserIds = taskForm.value.inspectionUsers.map((user) => user.userId);
|
||
} else {
|
||
taskForm.value.taskUserIds = [];
|
||
}
|
||
dialogTitle.value = '查看';
|
||
visible.value = true;
|
||
};
|
||
const handleDelete = async (id) => {
|
||
console.log('删除ID:', id);
|
||
const response = await deleteLandInspection(id);
|
||
if (response?.code === 200) {
|
||
ElMessage.success(response?.msg || '删除成功');
|
||
getData(); // 刷新数据
|
||
}
|
||
};
|
||
|
||
const handleResult = async (id) => {
|
||
console.log('结果登记ID:', id);
|
||
await handleView(id);
|
||
isReadonlyRegist.value = false;
|
||
dialogTitle.value = '结果登记';
|
||
illegalForm.value.inspectionId = id;
|
||
nextTick(() => {
|
||
visible.value = true;
|
||
});
|
||
};
|
||
const handleBack = async (id) => {
|
||
console.log('收回任务ID:', id);
|
||
const response = await updateLandInspectionStatus({
|
||
id,
|
||
status: '02',
|
||
});
|
||
ElMessage.success(response?.msg || '发布成功');
|
||
await getData();
|
||
};
|
||
const handlePublish = async (id) => {
|
||
console.log('发布任务ID:', id);
|
||
// updateLandInspectionStatus : status -1 => 00
|
||
const response = await updateLandInspectionStatus({
|
||
id,
|
||
status: '00',
|
||
});
|
||
ElMessage.success(response?.msg || '发布成功');
|
||
await getData();
|
||
};
|
||
const handleRePublish = async (id) => {
|
||
console.log('重新发布ID:', id);
|
||
const response = await updateLandInspectionStatus({
|
||
id,
|
||
status: '00',
|
||
});
|
||
ElMessage.success(response?.msg || '发布成功');
|
||
await getData();
|
||
};
|
||
const handleViewResult = async (row) => {
|
||
console.log('查看登记结果ID:', row.id);
|
||
await handleView(row.id);
|
||
isReadonlyRegist.value = true;
|
||
// const response = await getInspectionResultDetail(row.id);
|
||
// illegalForm.value = response.data;
|
||
dialogTitle.value = '查看登记结果';
|
||
nextTick(() => {
|
||
visible.value = true;
|
||
});
|
||
};
|
||
|
||
// 删除表单
|
||
const handleRemoveForm = async (index) => {
|
||
if (illegalForms.value[index].id) {
|
||
await deleteInspectionResult(illegalForms.value[index].id);
|
||
} else {
|
||
illegalForms.value.splice(index, 1);
|
||
}
|
||
};
|
||
|
||
const handleSubmit = async () => {
|
||
try {
|
||
console.log('表单数据:', taskForm.value);
|
||
console.log('表单数据:', illegalForm.value);
|
||
// 1. 表单验证(如果有refName)
|
||
loading.value = true;
|
||
let response;
|
||
// 2. 提交数据
|
||
if (dialogTitle.value === '新增') {
|
||
taskForm.value.id = '';
|
||
response = await createLandInspection(taskForm.value);
|
||
// 3. 处理成功响应(拦截器已处理200状态码)
|
||
ElMessage.success(response?.msg || '新增成功');
|
||
visible.value = false;
|
||
await getData();
|
||
} else if (dialogTitle.value === '编辑') {
|
||
response = await updateLandInspection(taskForm.value);
|
||
// 3. 处理成功响应(拦截器已处理200状态码)
|
||
ElMessage.success(response?.msg || '编辑成功');
|
||
visible.value = false;
|
||
await getData();
|
||
} else if (dialogTitle.value === '结果登记') {
|
||
// 1. 只保留没有 id 的新记录,并给它们补全 img 字段
|
||
const payload = illegalForms.value
|
||
.filter((item) => !item.id)
|
||
.map((item) => {
|
||
// 安全取第一张图
|
||
const firstImage = Array.isArray(item.illegalImages) && item.illegalImages.length ? item.illegalImages[0] : '';
|
||
return {
|
||
...item,
|
||
img: firstImage,
|
||
};
|
||
});
|
||
|
||
// 2. 如果没有新记录,直接提示并返回
|
||
if (payload.length === 0) {
|
||
ElMessage.warning('没有需要登记的新违法记录');
|
||
return;
|
||
}
|
||
|
||
// 3. 调用批量创建接口 —— 按后端期待的结构传参
|
||
response = await createInspectionResultBatch(payload);
|
||
|
||
ElMessage.success(response?.msg || '结果登记成功');
|
||
|
||
// 4. 完成后重新拉列表、关闭弹窗
|
||
await getData();
|
||
}
|
||
// 可刷新表格数据
|
||
} catch (e) {
|
||
ElMessage.error('保存失败');
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
};
|
||
const handleExport = async () => {
|
||
try {
|
||
const response = await exportLandInspection(searchForm.value);
|
||
if (response?.code === 200) {
|
||
// 假设返回的是文件下载链接
|
||
const link = document.createElement('a');
|
||
link.href = response.data; // 假设data是下载链接
|
||
link.download = 'land_inspection_export.xlsx'; // 设置下载文件名
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
document.body.removeChild(link);
|
||
ElMessage.success('导出成功');
|
||
} else {
|
||
ElMessage.error(response?.msg || '导出失败');
|
||
}
|
||
} catch (error) {
|
||
ElMessage.error('导出失败,请稍后重试');
|
||
}
|
||
};
|
||
function handleRefresh() {
|
||
console.log('刷新数据');
|
||
}
|
||
function handleAddForm() {
|
||
console.log('添加记录');
|
||
illegalForms.value.push({ ...illegalForm.value });
|
||
}
|
||
function handleCurrentChange(val) {
|
||
console.log('当前页:', val);
|
||
}
|
||
function handleSizeChange(val) {
|
||
console.log('每页显示条数:', val);
|
||
}
|
||
// ---------------------------------------------------------------------
|
||
// 页面权限控制相关
|
||
// ---------------------------------------------------------------------
|
||
|
||
// 如果user.admin是true就是operator,否则是inspector
|
||
const role = ref('operator');
|
||
if (user.admin) {
|
||
role.value = 'operator';
|
||
} else {
|
||
role.value = 'inspector';
|
||
}
|
||
// 所有操作项
|
||
const allActions = [
|
||
{ name: '查看', icon: 'view', key: 'view', event: ({ row }) => handleView(row.id) },
|
||
{ name: '编辑', icon: 'edit', key: 'edit', event: ({ row }) => handleEdit(row.id) },
|
||
{ name: '删除', icon: 'delete', key: 'delete', type: 'danger', event: ({ row }) => handleDelete(row.id) },
|
||
{ name: '结果登记', icon: 'result', key: 'result', event: ({ row }) => handleResult(row.id) },
|
||
{ name: '收回任务', icon: 'back', key: 'back', event: ({ row }) => handleBack(row.id) },
|
||
{ name: '发布任务', icon: 'publish', key: 'publish', event: ({ row }) => handlePublish(row.id) },
|
||
{ name: '重新发布', icon: 're-publish', key: 'rePublish', event: ({ row }) => handleRePublish(row.id) },
|
||
{ name: '查看登记结果', icon: 'view-result', key: 'viewResult', event: ({ row }) => handleViewResult(row) },
|
||
];
|
||
// 权限表(角色 -> 可操作项)
|
||
const permissionMap = {
|
||
admin: ['operator', 'inspector'], // 继承 operator 和 inspector 的权限
|
||
operator: ['view', 'edit', 'delete', 'publish', 'back', 'rePublish', 'viewResult'],
|
||
inspector: ['result', 'viewResult'],
|
||
};
|
||
// 状态控制表(状态码 -> 可操作项)
|
||
const statusMap = {
|
||
'-1': ['view', 'edit', 'delete', 'publish'],
|
||
'00': ['result', 'back', 'viewResult'],
|
||
'01': ['viewResult'],
|
||
'02': ['view', 'edit', 'delete', 'rePublish'],
|
||
};
|
||
function getActions(row) {
|
||
// 1. 先拿到当前角色对应的“原始权限”列表(可能是 action.key 也可能是继承的子角色名)
|
||
let raw = permissionMap[role.value] || [];
|
||
|
||
// 2. 如果 raw 里有子角色(即 permissionMap 中也存在该 key),则把它平铺展开
|
||
const expanded = raw.reduce((acc, key) => {
|
||
if (permissionMap[key]) {
|
||
// key 是个角色,取它的 action.key 列表
|
||
acc.push(...permissionMap[key]);
|
||
} else {
|
||
// key 不是角色,直接当作 action.key
|
||
acc.push(key);
|
||
}
|
||
return acc;
|
||
}, []);
|
||
|
||
// 去重
|
||
const roleAllowed = Array.from(new Set(expanded));
|
||
|
||
// 3. 根据当前行状态拿到状态允许的 action.key
|
||
// 假设 row.inspectionStatus 或 row.status 存储了状态码
|
||
const statusKey = row.inspectionStatus ?? row.status;
|
||
const statusAllowed = statusMap[statusKey] || [];
|
||
|
||
// 4. 最终只取角色和状态都允许的 key
|
||
const finalKeys = roleAllowed.filter((key) => statusAllowed.includes(key));
|
||
|
||
// 5. 根据 finalKeys 过滤 allActions,并保持原始顺序
|
||
return allActions.filter((a) => finalKeys.includes(a.key));
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
:deep(.el-dialog__body) {
|
||
padding: 20px;
|
||
height: calc(100vh - 300px);
|
||
overflow-y: auto;
|
||
}
|
||
.form-container {
|
||
position: relative;
|
||
border: 1px solid #ebeef5;
|
||
border-radius: 4px;
|
||
padding: 15px;
|
||
margin-bottom: 20px;
|
||
}
|
||
.form-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
padding-bottom: 10px;
|
||
border-bottom: 1px solid #eee;
|
||
}
|
||
.form-footer {
|
||
margin-top: 20px;
|
||
text-align: center;
|
||
}
|
||
.form-group {
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
margin: 30px 0;
|
||
color: #333333;
|
||
}
|
||
</style>
|