@@ -23,5 +23,5 @@ VITE_HTTP_PROXY = true | |||
# 开发环境跨域代理,支持配置多个 | |||
# VITE_PROXY = [["/api","http://192.168.10.186:5566","/Files"]] | |||
VITE_PROXY = [["/api","http://192.168.10.186:8003"],["/Files","artc://rts-pull-live.deepeleph.com"]] | |||
VITE_PROXY = [["/api","http://192.168.10.186:8003"],["/Files","http://192.168.10.186:8003/Files"]] | |||
@@ -26,6 +26,8 @@ export namespace SysDormitory { | |||
name?: string | undefined; | |||
gender?: boolean | undefined; | |||
createTime?: string | undefined; | |||
insCameraId?: string | number | undefined; | |||
outCameraId?: string | number | undefined; | |||
} | |||
// 寝室列表传参 | |||
export interface Page extends ReqPage { | |||
@@ -4,7 +4,7 @@ | |||
* @Date: 2023-12-15 15:38:32 | |||
!--> | |||
<template> | |||
<el-select :placeholder="placeholder" class="w-full" v-bind="$attrs" clearable> | |||
<el-select :placeholder="placeholder" :filterable="filterable" class="w-full" v-bind="$attrs" clearable> | |||
<el-option v-for="(item, index) in options" :key="index" :label="item[props.label]" :value="item[props.value]" /> | |||
</el-select> | |||
</template> | |||
@@ -20,7 +20,8 @@ const props = withDefaults(defineProps<SSelectProps>(), { | |||
options: [] as any, | |||
value: "value", | |||
label: "label", | |||
button: false | |||
button: false, | |||
filterable: false //是否可搜索 | |||
}); | |||
const placeholder = computed(() => { | |||
@@ -21,4 +21,5 @@ export interface SSelectProps { | |||
label?: string; | |||
/** 选项值 */ | |||
value?: string; | |||
filterable?: boolean; | |||
} |
@@ -20,7 +20,15 @@ | |||
</div> | |||
</div> | |||
<!-- 表格主体 --> | |||
<el-table ref="tableRef" v-bind="$attrs" :data="processTableData" :border="border" :row-key="rowKey" @selection-change="selectionChange"> | |||
<el-table | |||
ref="tableRef" | |||
v-bind="$attrs" | |||
:data="processTableData" | |||
:border="border" | |||
:max-height="maxHeight" | |||
:row-key="rowKey" | |||
@selection-change="selectionChange" | |||
> | |||
<!-- 默认插槽 --> | |||
<slot /> | |||
<template v-for="item in tableColumns" :key="item"> | |||
@@ -113,6 +121,7 @@ export interface ProTableProps { | |||
rowKey?: string; // 行数据的 Key,用来优化 Table 的渲染,当表格数据多选时,所指定的 id ==> 非必传(默认为 id) | |||
searchCol?: number | Record<BreakPoint, number>; // 表格搜索项 每列占比配置 ==> 非必传 { xs: 1, sm: 2, md: 2, lg: 3, xl: 4 } | |||
pagerCount?: number; // 分页组件显示最大页码按钮数 ==> 非必传(默认为7) | |||
maxHeight?: number | string; | |||
} | |||
// 接受父组件参数,配置默认值 | |||
@@ -52,7 +52,7 @@ | |||
</el-tabs> | |||
</el-col> | |||
<el-col :span="10"> | |||
<ProTable ref="userTable" :columns="columns" :tool-button="false" :init-param="initParam" :request-api="userSelectorApi"> | |||
<ProTable ref="userTable" :columns="columns" maxHeight="480" :tool-button="false" :init-param="initParam" :request-api="userSelectorApi"> | |||
<!-- 表格 header 按钮 --> | |||
<template #tableHeader="scope"> | |||
<el-button type="primary" @click="addRecords(userTable!.tableData)">添加当前</el-button> | |||
@@ -65,7 +65,15 @@ | |||
</ProTable> | |||
</el-col> | |||
<el-col :span="10"> | |||
<ProTable ref="chooseTable" :columns="columns" :tool-button="true" :data="chooseDataTmp" @search="searchRecords" @reset="resetRecords"> | |||
<ProTable | |||
ref="chooseTable" | |||
:columns="columns" | |||
maxHeight="480" | |||
:tool-button="true" | |||
:data="chooseDataTmp" | |||
@search="searchRecords" | |||
@reset="resetRecords" | |||
> | |||
<!-- 表格 header 按钮 --> | |||
<template #tableHeader="scope"> | |||
<el-button type="danger" @click="delRecords(chooseTable!.tableData)">删除当前</el-button> | |||
@@ -84,12 +92,18 @@ | |||
</el-row> | |||
</div> | |||
<template #footer> | |||
<div class="mt-20px"> | |||
<div> | |||
<el-button @click="onClose"> 取消 </el-button> | |||
<el-button type="primary" @click="handleOk"> 确定 </el-button> | |||
</div> | |||
</template> | |||
</form-container> | |||
<!-- 预览头像 --> | |||
<el-dialog v-model="imgVisible" title="查看头像" width="830px" :before-close="handleClose"> | |||
<div style="display: flex; align-items: center; justify-content: center"> | |||
<img style="max-width: 100%; max-height: 600px" class="detailpic" :src="faceUrl" alt="" /> | |||
</div> | |||
</el-dialog> | |||
</template> | |||
<script setup lang="tsx" name="UserSelector"> | |||
@@ -104,7 +118,16 @@ const emit = defineEmits({ successful: null }); // 自定义事件 | |||
// console.log(tab, event); | |||
// }; | |||
const visible = ref(false); //是否显示 | |||
const imgVisible = ref(false); //是否显示寝室表单 | |||
const faceUrl = ref(''); | |||
const viewHeadImage = (scope: any) => { | |||
faceUrl.value = scope.row.faces[0].faceUrl; | |||
imgVisible.value = true | |||
console.log(faceUrl); | |||
}; | |||
const handleClose = () => { | |||
imgVisible.value = false; | |||
}; | |||
// 定义组件props | |||
const props = withDefaults(defineProps<UserSelectProps>(), { | |||
multiple: false, | |||
@@ -112,7 +135,7 @@ const props = withDefaults(defineProps<UserSelectProps>(), { | |||
}); | |||
// 根据是否业务显示不同名称 | |||
const userName = props.biz ? "人员" : "用户"; | |||
const userName = props.biz ? "用户" : "人员"; | |||
const positionName = props.biz ? "职位" : "岗位"; | |||
const orgName = props.biz ? "机构" : "班级"; | |||
@@ -132,7 +155,7 @@ const columns: ColumnProps<SysUser.SysUserInfo>[] = [ | |||
label: "人脸", | |||
render: scope => { | |||
return ( | |||
<img src={scope.row.faces.length > 0 ? scope.row.faces[0].faceUrl : ''} onClick={() => viewHeadImage(scope)} style='width:50px;height:50px;' alt=''/> | |||
<img src={scope.row.faces.length > 0 ? scope.row.faces[0].faceUrl : ''} onClick={() => viewHeadImage(scope)} style='width:30px;height:30px;' alt=''/> | |||
); | |||
} | |||
}, | |||
@@ -162,6 +185,10 @@ function onClose() { | |||
/** 提交数据 */ | |||
function handleOk() { | |||
if (chooseData.value.length == 0) { | |||
ElMessage.warning("请选择" + userName); | |||
return; | |||
} | |||
visible.value = false; | |||
console.log(chooseData.value,'提交得数据') | |||
emit("successful", chooseData.value); | |||
@@ -158,7 +158,7 @@ function getDataChart() { | |||
}); | |||
}); | |||
} | |||
function getCharts1(data) { | |||
function getCharts1(data: any) { | |||
const chart = echarts.init(chart1.value); | |||
const option = { | |||
tooltip: { | |||
@@ -208,7 +208,7 @@ function getCharts1(data) { | |||
chart.resize(); | |||
}); | |||
} | |||
function getCharts2(data) { | |||
function getCharts2(data: any) { | |||
const chartstation = echarts.init(chart2.value); | |||
const option = { | |||
tooltip: { | |||
@@ -261,22 +261,22 @@ function getCharts2(data) { | |||
function getWeekData() { | |||
setTimeout(async () => { | |||
await statistionApi.weekstatistion({}).then(res => { | |||
await statistionApi.weekstatistion({}).then((res: any) => { | |||
let { code, data } = res; | |||
if (code == 200) { | |||
// let chartData = data; | |||
let time = data.dataX; | |||
let chartData = data.dataY.map(item => { | |||
let chartData = data.dataY.map((item: any) => { | |||
return { | |||
data: item.data, | |||
name: item.name, | |||
type: "bar", | |||
barWidth: "12px", // 设置柱子粗细 | |||
itemStyle: { | |||
normal: { | |||
barBorderRadius: [30, 30, 0, 0] | |||
} | |||
// normal: { | |||
borderRadius: [30, 30, 0, 0] | |||
// } | |||
} | |||
}; | |||
}); | |||
@@ -285,7 +285,7 @@ function getWeekData() { | |||
}); | |||
}); | |||
} | |||
function getCharts3(time, data) { | |||
function getCharts3(time: any, data: any) { | |||
const chartstation3 = echarts.init(chart3.value); | |||
const option = { | |||
tooltip: { | |||
@@ -27,6 +27,28 @@ | |||
<s-radio-group v-model="sysDormitoryProps.record.gender" :options="genderOptions" /> | |||
</s-form-item> | |||
</el-col> | |||
<el-col :span="22"> | |||
<s-form-item label="进楼摄像头" prop="insCameraId"> | |||
<s-select | |||
v-model="sysDormitoryProps.record.insCameraId" | |||
:filterable="true" | |||
:options="creamaData" | |||
label="sensorName" | |||
value="sensorId" | |||
></s-select> | |||
</s-form-item> | |||
</el-col> | |||
<el-col :span="22"> | |||
<s-form-item label="出楼摄像头" prop="outCameraId"> | |||
<s-select | |||
v-model="sysDormitoryProps.record.outCameraId" | |||
:filterable="true" | |||
:options="creamaData" | |||
label="sensorName" | |||
value="sensorId" | |||
></s-select> | |||
</s-form-item> | |||
</el-col> | |||
</el-row> | |||
</div> | |||
</el-form> | |||
@@ -40,12 +62,13 @@ | |||
<script setup lang="ts" name="SysDormitoryformClass"> | |||
import { ref } from "vue"; | |||
import { SysDormitory, userManageDormitoryApi } from "@/api"; | |||
import { SysDormitory, userManageDormitoryApi, monitorLIVEApi } from "@/api"; | |||
import { FormOptEnum } from "@/enums"; | |||
import { required } from "@/utils/formRules"; | |||
import { FormInstance } from "element-plus"; | |||
const visibleDormitory = ref(false); //是否显示表单 | |||
const creamaData = ref<any>([]); | |||
const genderOptions = [ | |||
{ | |||
label: "男", | |||
@@ -65,7 +88,9 @@ const sysDormitoryProps = reactive<FormProps.Base<SysDormitory.DormitoryInfo>>({ | |||
// 表单验证规则 | |||
const rules = reactive({ | |||
name: [required("请输入宿舍楼名称")], | |||
gender: [required("请选择性别")] | |||
gender: [required("请选择性别")], | |||
insCameraId: [required("请选择进楼摄像头")], | |||
outCameraId: [required("请选择出楼摄像头")] | |||
}); | |||
/** | |||
@@ -113,7 +138,14 @@ async function handleSubmit() { | |||
function onClose() { | |||
visibleDormitory.value = false; | |||
} | |||
onMounted(() => { | |||
getCreamaList(); | |||
}); | |||
const getCreamaList = () => { | |||
monitorLIVEApi.list({ pageNum: 1, pageSize: 1000 }).then(res => { | |||
creamaData.value = res.data.list; | |||
}); | |||
}; | |||
// 暴露给父组件的方法 | |||
defineExpose({ | |||
onOpen | |||
@@ -1,7 +1,7 @@ | |||
<!-- | |||
* @Description: 寝室管理 | |||
* @Author: syy | |||
* @Date: 2024-7-15 | |||
* @Author: wwp | |||
* @Date: 2024-7-25 | |||
--> | |||
<template> | |||
<div class="main-box"> | |||
@@ -17,6 +17,7 @@ | |||
> | |||
<template v-slot:header> | |||
<s-button suffix="宿舍楼" @click="addDormitory(FormOptEnum.ADD)" style="margin-bottom: 15px" /> | |||
<el-button @click="settingTime" style="margin-bottom: 15px">归寝时间设置</el-button> | |||
</template> | |||
<template v-slot:label="{ row }"> | |||
<span class="custom-tree-node"> | |||
@@ -65,28 +66,59 @@ | |||
</el-space> | |||
</template> | |||
</ProTable> | |||
<ClassUserselector | |||
ref="userSelectorRef" | |||
:org-tree-api="userManageClassManageApi.page" | |||
:user-selector-api="userManagePersonnelApi.page" | |||
multiple | |||
@successful="handleChooseUser" | |||
> | |||
</ClassUserselector> | |||
</div> | |||
<!-- 寝室新增/编辑表单 --> | |||
<Form ref="formRef"></Form> | |||
<!-- 宿舍楼新增/编辑表单 --> | |||
<FormDormitory ref="formRefD" /> | |||
<!-- 班主任绑定/修改 --> | |||
<!-- :user-selector-params="{ orgId: orgId }" --> | |||
<ClassUserselector | |||
ref="userSelectorRef" | |||
:org-tree-api="userManageClassManageApi.page" | |||
:org-tree-props="{ label: 'name', children: 'children' }" | |||
:user-selector-api="userManagePersonnelApi.page" | |||
multiple | |||
@successful="handleChooseUser" | |||
> | |||
</ClassUserselector> | |||
<!-- <formUser ref="formRefU" /> --> | |||
<!-- 预览头像 --> | |||
<el-dialog v-model="visible" title="查看头像" width="830px" :before-close="handleClose"> | |||
<div style="display: flex; align-items: center; justify-content: center"> | |||
<img style="max-width: 100%; max-height: 600px" class="detailpic" :src="faceUrl" alt="" /> | |||
</div> | |||
<el-dialog v-model="timeVisible" title="归寝时间设置" :before-close="closeTime"> | |||
<el-form :model="timeForm" :rules="timeRules" ref="timeFormRef" label-width="100px"> | |||
<el-row> | |||
<el-col :span="16"> | |||
<el-form-item label="功能有效期:" prop="dateArr"> | |||
<el-date-picker | |||
v-model="timeForm.dateArr" | |||
type="daterange" | |||
format="YYYY-MM-DD" | |||
value-format="YYYY-MM-DD" | |||
range-separator="-" | |||
start-placeholder="开始日期" | |||
end-placeholder="结束日期" | |||
:size="size" | |||
/> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="16"> | |||
<el-form-item label="布防时间:" prop="timeArr"> | |||
<el-time-picker | |||
v-model="timeForm.timeArr" | |||
format="HH:mm:ss" | |||
value-format="HH:mm:ss" | |||
is-range | |||
range-separator="-" | |||
start-placeholder="开始时间" | |||
end-placeholder="结束时间" | |||
/> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
</el-form> | |||
<template #footer> | |||
<div class="dialog-footer"> | |||
<el-button type="primary" @click="onTimeSubmit">提交</el-button> | |||
<el-button @click="closeTime">取消</el-button> | |||
</div> | |||
</template> | |||
</el-dialog> | |||
</div> | |||
</template> | |||
@@ -105,8 +137,7 @@ import { TokenEnum } from "@/enums"; | |||
import type { UploadProps } from "element-plus"; | |||
import { UserSelectorInstance } from "@/components/Selectors/UserSelector/interface"; | |||
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数) | |||
const faceUrl = ref(''); | |||
const visible = ref(false); //是否显示寝室表单 | |||
const proTable = ref<ProTableInstance>(); | |||
const treeFilter = ref<InstanceType<typeof TreeFilter> | null>(null); | |||
const userStore = useUserStore(); | |||
@@ -128,17 +159,63 @@ const columns: ColumnProps<SysDormitory.ChamberInfo>[] = [ | |||
}, | |||
{ prop: "operation", label: "操作", width: 250, fixed: "right" } | |||
]; | |||
const viewHeadImage = (scope: any) => { | |||
faceUrl.value = scope.row.faces[0].faceUrl; | |||
visible.value = true | |||
console.log(faceUrl); | |||
const size = ref<'default' | 'large' | 'small'>('default') | |||
const timeVisible = ref(false); //是否显示时间设置 | |||
const timeForm = reactive({ | |||
dateArr: [], | |||
timeArr: [], | |||
}); | |||
const timeRules = ref({ | |||
dateArr: [{ required: true, message: "请选择功能有效期", trigger: "change" }], | |||
timeArr: [{ required: true, message: "请选择布防时间", trigger: "change" }], | |||
}); | |||
const timeFormRef = ref<any>(null); | |||
const settingTime = () => { | |||
timeVisible.value = true; | |||
getTimeDetail() | |||
}; | |||
const handleClose = () => { | |||
visible.value = false; | |||
const getTimeDetail = () => { | |||
userManageDormitoryApi.getReturnTime().then((res:any) => { | |||
timeForm.dateArr = [res.data.funcStart,res.data.funcEnd]; | |||
timeForm.timeArr = [res.data.timeBegin,res.data.timeEnd]; | |||
}); | |||
} | |||
const closeTime = () => { | |||
timeForm.dateArr = []; | |||
timeForm.timeArr = []; | |||
timeVisible.value = false; | |||
}; | |||
// 提交分组 | |||
const onTimeSubmit = () => { | |||
timeFormRef.value.validate((valid: any) => { | |||
if (valid) { | |||
let params: any = reactive({ | |||
funcStart: timeForm.dateArr[0], | |||
funcEnd: timeForm.dateArr[1], | |||
timeBegin: timeForm.timeArr[0], | |||
timeEnd: timeForm.timeArr[1] | |||
}); | |||
userManageDormitoryApi.setReturnTime(params).then((res:any) => { | |||
if (res.code == 200) { | |||
// getGroupList(); | |||
ElMessage({ | |||
message: res.msg, | |||
type: 'success' | |||
}); | |||
closeTime(); | |||
} | |||
}); | |||
} else { | |||
return false; | |||
} | |||
}); | |||
}; | |||
// 确定人员 | |||
function handleChooseUser(data: SysUser.SysUserInfo[]) { | |||
console.log(data) | |||
//组装参数 | |||
const grantUser: SysRole.GrantUserReq = { | |||
// id: roleId.value, | |||
@@ -146,7 +223,13 @@ const handleClose = () => { | |||
dormitoryId: chamberId.value, | |||
personIds: data.map(item => item.personId) as number[] | string[], | |||
}; | |||
userManageDormitoryApi.setAssignPerson(grantUser); | |||
userManageDormitoryApi.setAssignPerson(grantUser).then(res => { | |||
ElMessage({ | |||
message: res.msg, | |||
type: 'success' | |||
}); | |||
RefreshTable(); | |||
}) | |||
} | |||
// 寝室表单引用 | |||
const formRef = ref<InstanceType<typeof Form> | null>(null); | |||
@@ -248,9 +331,11 @@ const chamberId = ref<number | string>(); //寝室id | |||
function handleCommand(command: Command) { | |||
switch (command.command) { | |||
case cmdEnum.AddPerson: | |||
console.log(111) | |||
// addPerson(FormOptEnum.add, command.row) | |||
userSelectorRef.value?.showSelector(); //显示用户选择器 | |||
userManageDormitoryApi.detail({ id: command.row.id }).then(res => { | |||
console.log(res) | |||
userSelectorRef.value?.showSelector(res.data.personInfos); //显示用户选择器 | |||
}); | |||
chamberId.value = command.row.id; //获取寝室id | |||
break; | |||
} | |||
@@ -36,17 +36,17 @@ onMounted(() => { | |||
}); | |||
function getDataChart() { | |||
setTimeout(async () => { | |||
await statistionApi.warnstatistion({}).then(res => { | |||
await statistionApi.warnstatistion({}).then((res: any) => { | |||
let { code, data } = res; | |||
if (code == 200) { | |||
let chartData1 = data.alarm.map(item => { | |||
let chartData1 = data.alarm.map((item: any) => { | |||
return { | |||
value: item.count, | |||
name: item.name | |||
}; | |||
}); | |||
let chartData2 = data.hand.map(item => { | |||
let chartData2 = data.hand.map((item: any) => { | |||
return { | |||
value: item.count, | |||
name: item.name | |||
@@ -68,7 +68,7 @@ function getDataChart() { | |||
}); | |||
}); | |||
} | |||
function getCharts1(data) { | |||
function getCharts1(data: any) { | |||
const chart = echarts.init(chart1.value); | |||
const option = { | |||
title: { | |||
@@ -105,7 +105,7 @@ function getCharts1(data) { | |||
chart.resize(); | |||
}); | |||
} | |||
function getCharts2(data) { | |||
function getCharts2(data: any) { | |||
const chartstation = echarts.init(chart2.value); | |||
const option = { | |||
title: { | |||
@@ -142,39 +142,23 @@ function getCharts2(data) { | |||
chartstation.resize(); | |||
}); | |||
} | |||
function flattenArray(arr) { | |||
const result = []; | |||
arr.forEach(item => { | |||
if (Array.isArray(item)) { | |||
result.push(...flattenArray(item)); | |||
} else { | |||
result.push(item); | |||
} | |||
}); | |||
return result; | |||
} | |||
function unique(arr) { | |||
return arr.filter((item, index, arr) => arr.indexOf(item, 0) === index); | |||
} | |||
function getWeekData() { | |||
setTimeout(async () => { | |||
await statistionApi.weekstatistion({}).then(res => { | |||
await statistionApi.weekstatistion({}).then((res: any) => { | |||
let { code, data } = res; | |||
if (code == 200) { | |||
// let chartData = data; | |||
let time = data.dataX; | |||
let chartData = data.dataY.map(item => { | |||
let chartData = data.dataY.map((item: any) => { | |||
return { | |||
data: item.data, | |||
name: item.name, | |||
type: "bar", | |||
barWidth: "12px", // 设置柱子粗细 | |||
itemStyle: { | |||
normal: { | |||
barBorderRadius: [30, 30, 0, 0] | |||
} | |||
borderRadius: [30, 30, 0, 0] | |||
} | |||
}; | |||
}); | |||
@@ -183,7 +167,7 @@ function getWeekData() { | |||
}); | |||
}); | |||
} | |||
function getCharts3(time, data) { | |||
function getCharts3(time: any, data: any) { | |||
const chartstation3 = echarts.init(chart3.value); | |||
const option = { | |||
title: { | |||
@@ -228,21 +212,20 @@ function getCharts3(time, data) { | |||
height: 50px; | |||
line-height: 50px; | |||
} | |||
.collapse-title { | |||
flex: 1 0 90%; | |||
order: 1; | |||
display: flex; | |||
flex: 1 0 90%; | |||
align-items: center; | |||
justify-content: space-between; | |||
// padding: 30px 0; | |||
order: 1; | |||
// padding: 30px 0; | |||
.titlemodel { | |||
margin-right: 40px; | |||
// display: inline-block; | |||
font-size: 18px; | |||
margin-right: 40px; | |||
} | |||
.btns { | |||
margin-left: 40px; | |||
} | |||
@@ -250,19 +233,22 @@ function getCharts3(time, data) { | |||
.collapse-content { | |||
padding: 20px; | |||
.contentinfo { | |||
margin-top: 20px; | |||
box-sizing: border-box; | |||
// display: flex; | |||
// justify-content: space-between; | |||
// align-items: center; | |||
padding: 20px 20px; | |||
box-sizing: border-box; | |||
padding: 20px; | |||
margin-top: 20px; | |||
// border-bottom: 1px solid #dcdfe6; | |||
// background: red; | |||
border-radius: 10px; | |||
// box-shadow: 3px 3px 3px #00000014, 3px -3px 3px #00000014, -3px 3px 3px #00000014, -3px -3px 3px #00000014; | |||
// box-shadow: 0 1px 1px hsl(0deg 0% 0% / 0.075), 0 2px 2px hsl(0deg 0% 0% / 0.075), 0 4px 4px hsl(0deg 0% 0% / 0.075), | |||
// 0 8px 8px hsl(0deg 0% 0% / 0.075), 0 16px 16px hsl(0deg 0% 0% / 0.075); | |||
box-shadow: 0px 2px 1px rgba(0, 0, 0, 0.1), 0 0px 8px rgba(0, 0, 0, 0.1), 0 -1px 1px #fff, 0px 0 0px #fff, 0 0 16px #fff; | |||
box-shadow: 0 2px 1px rgb(0 0 0 / 10%), 0 0 8px rgb(0 0 0 / 10%), 0 -1px 1px #ffffff, 0 0 0 #ffffff, 0 0 16px #ffffff; | |||
.modellabel { | |||
font-size: 16px; | |||
} | |||