master
parent
e1df05b96e
commit
f812ce5d43
|
@ -50,7 +50,7 @@
|
|||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #FF0000;
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@
|
|||
.helps pre {
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
border: solid 1px #E7E1CD;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
overflow: auto;
|
||||
}
|
||||
|
@ -218,7 +218,7 @@
|
|||
.markdown > p,
|
||||
.markdown > blockquote,
|
||||
.markdown > .highlight,
|
||||
.markdown > ol,
|
||||
.markdown >ol,
|
||||
.markdown>ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
@ -288,7 +288,7 @@
|
|||
|
||||
.markdown blockquote {
|
||||
font-size: 90%;
|
||||
color: #999999;
|
||||
color: #999;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
padding-left: 0.8em;
|
||||
margin: 1em 0;
|
||||
|
@ -318,7 +318,7 @@
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown > br,
|
||||
.markdown >br,
|
||||
.markdown>p>br {
|
||||
clear: both;
|
||||
}
|
||||
|
@ -378,12 +378,12 @@
|
|||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55A532;
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #BD2C00;
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,15 +55,15 @@
|
|||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">menu</div>
|
||||
<div class="code-name">&#xe667;</div>
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">igw-f-contact</div>
|
||||
<div class="code-name">&#xe61f;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">menu_3rolepermiss</div>
|
||||
<div class="code-name">&#xe689;</div>
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">menu</div>
|
||||
<div class="code-name">&#xe667;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
|
@ -156,9 +156,9 @@
|
|||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1753872505940') format('woff2'),
|
||||
url('iconfont.woff?t=1753872505940') format('woff'),
|
||||
url('iconfont.ttf?t=1753872505940') format('truetype');
|
||||
src: url('iconfont.woff2?t=1753923827999') format('woff2'),
|
||||
url('iconfont.woff?t=1753923827999') format('woff'),
|
||||
url('iconfont.ttf?t=1753923827999') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
|
@ -184,6 +184,15 @@
|
|||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-igw-f-role"></span>
|
||||
<div class="name">
|
||||
igw-f-contact
|
||||
</div>
|
||||
<div class="code-name">.icon-igw-f-role
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-menu"></span>
|
||||
<div class="name">
|
||||
|
@ -193,15 +202,6 @@
|
|||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-menu_rolepermiss"></span>
|
||||
<div class="name">
|
||||
menu_3rolepermiss
|
||||
</div>
|
||||
<div class="code-name">.icon-menu_rolepermiss
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-cog"></span>
|
||||
<div class="name">
|
||||
|
@ -339,18 +339,18 @@
|
|||
|
||||
<li class="dib">
|
||||
<svg aria-hidden="true" class="icon svg-icon">
|
||||
<use xlink:href="#icon-menu"></use>
|
||||
<use xlink:href="#icon-igw-f-role"></use>
|
||||
</svg>
|
||||
<div class="name">menu</div>
|
||||
<div class="code-name">#icon-menu</div>
|
||||
<div class="name">igw-f-contact</div>
|
||||
<div class="code-name">#icon-igw-f-role</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg aria-hidden="true" class="icon svg-icon">
|
||||
<use xlink:href="#icon-menu_rolepermiss"></use>
|
||||
<use xlink:href="#icon-menu"></use>
|
||||
</svg>
|
||||
<div class="name">menu_3rolepermiss</div>
|
||||
<div class="code-name">#icon-menu_rolepermiss</div>
|
||||
<div class="name">menu</div>
|
||||
<div class="code-name">#icon-menu</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4985351 */
|
||||
src: url('iconfont.woff2?t=1753872505940') format('woff2'),
|
||||
url('iconfont.woff?t=1753872505940') format('woff'),
|
||||
url('iconfont.ttf?t=1753872505940') format('truetype');
|
||||
src: url('iconfont.woff2?t=1753923827999') format('woff2'),
|
||||
url('iconfont.woff?t=1753923827999') format('woff'),
|
||||
url('iconfont.ttf?t=1753923827999') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,12 +13,12 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-menu:before {
|
||||
content: "\e667";
|
||||
.icon-igw-f-role:before {
|
||||
content: "\e61f";
|
||||
}
|
||||
|
||||
.icon-menu_rolepermiss:before {
|
||||
content: "\e689";
|
||||
.icon-menu:before {
|
||||
content: "\e667";
|
||||
}
|
||||
|
||||
.icon-cog:before {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,13 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "24493756",
|
||||
"name": "igw-f-contact",
|
||||
"font_class": "igw-f-role",
|
||||
"unicode": "e61f",
|
||||
"unicode_decimal": 58911
|
||||
},
|
||||
{
|
||||
"icon_id": "1174312",
|
||||
"name": "menu",
|
||||
|
@ -12,13 +19,6 @@
|
|||
"unicode": "e667",
|
||||
"unicode_decimal": 58983
|
||||
},
|
||||
{
|
||||
"icon_id": "12891317",
|
||||
"name": "menu_3rolepermiss",
|
||||
"font_class": "menu_rolepermiss",
|
||||
"unicode": "e689",
|
||||
"unicode_decimal": 59017
|
||||
},
|
||||
{
|
||||
"icon_id": "1261484",
|
||||
"name": "cog",
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -10,3 +10,9 @@ html {
|
|||
#app {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
.ix-modal-wrapper,
|
||||
.ix-mask {
|
||||
position: absolute;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import { reloadUserInfo } from '@/common/app'
|
|||
enum SpecialPage {
|
||||
Main = 'main',
|
||||
Login = 'login',
|
||||
Home = 'home',
|
||||
Home = 'tsp',
|
||||
NotFund = 'notFund'
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ function errHandler({code, msg, message}: R) {
|
|||
console.log(msg, message)
|
||||
break
|
||||
default:
|
||||
Toast.error(message)
|
||||
Toast.error(message ?? '操作失败')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,9 @@ httpUtil.interceptors.response.use(
|
|||
response => {
|
||||
// console.log('HTTP 请求结果', response.config.url, response)
|
||||
// vite 代理失败时 响应码为 200 响应内容为空
|
||||
if (response.config.responseType !== 'json') {
|
||||
return Promise.resolve(response)
|
||||
}
|
||||
if (response.data == null) {
|
||||
response.data = {code: 99999, msg: '无响应内容', message: '无响应内容', data: null, headers: response.headers}
|
||||
}
|
||||
|
@ -204,6 +207,62 @@ export function postMltForm<T>(url: string, body: any, config?: AxiosConfig, dis
|
|||
})
|
||||
}
|
||||
|
||||
function getFileName(contentDisposition: string) {
|
||||
// 检查content-disposition是否存在
|
||||
if (!contentDisposition) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 查找filename=部分
|
||||
const match = contentDisposition.match(/filename=(.+)/)
|
||||
if (!match || match.length < 2) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 提取并解码文件名
|
||||
const fileNameEncoded = match[1].trim()
|
||||
// 移除可能存在的引号
|
||||
const fileNameWithoutQuotes = fileNameEncoded.replace(/["']/g, '')
|
||||
// 解码URL编码的字符串
|
||||
return decodeURIComponent(fileNameWithoutQuotes)
|
||||
}
|
||||
|
||||
export function download(url: string, params?: any, disposeErr: boolean = true) {
|
||||
return httpUtil.get(url, {params, paramsSerializer, responseType: 'arraybuffer'})
|
||||
.then(res => {
|
||||
let data = res.data
|
||||
if (!data || data.byteLength <= 0) {
|
||||
// 错误提示
|
||||
return
|
||||
}
|
||||
const contentDisposition = res.headers['Content-Disposition'] ?? res.headers['content-disposition']
|
||||
const fileName = getFileName(contentDisposition) ?? '下载的文件'
|
||||
// 将二进制流转为blob
|
||||
const blob = new Blob([ data ])
|
||||
// 创建新的URL并指向File对象或者Blob对象的地址
|
||||
const blobURL = window.URL.createObjectURL(blob)
|
||||
// 创建a标签,用于跳转至下载链接
|
||||
const tempLink = document.createElement('a')
|
||||
tempLink.style.display = 'none'
|
||||
tempLink.href = blobURL
|
||||
tempLink.setAttribute('download', decodeURI(fileName))
|
||||
// 兼容:某些浏览器不支持HTML5的download属性
|
||||
if (typeof tempLink.download === 'undefined') {
|
||||
tempLink.setAttribute('target', '_blank')
|
||||
}
|
||||
// 挂载a标签
|
||||
document.body.appendChild(tempLink)
|
||||
tempLink.click()
|
||||
document.body.removeChild(tempLink)
|
||||
// 释放blob URL地址
|
||||
window.URL.revokeObjectURL(blobURL)
|
||||
})
|
||||
.catch(res => {
|
||||
if (disposeErr) errHandler(res.response.data)
|
||||
return Promise.reject(res.response.data)
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
|
|
|
@ -13,6 +13,7 @@ import { DateObjectUnits } from 'luxon/src/datetime'
|
|||
*/
|
||||
|
||||
export enum FMT {
|
||||
month = 'yyyy-MM',
|
||||
date = 'yyyy-MM-dd',
|
||||
time = 'HH:mm',
|
||||
time_sec = 'HH:mm:ss',
|
||||
|
|
|
@ -2,8 +2,8 @@ export {}
|
|||
|
||||
declare global {
|
||||
namespace IconfontTypes {
|
||||
type name = 'menu'
|
||||
| 'menu_rolepermiss'
|
||||
type name = 'igw-f-role'
|
||||
| 'menu'
|
||||
| 'cog'
|
||||
| 'user'
|
||||
| 'bar-chart'
|
||||
|
|
|
@ -4,7 +4,12 @@ import { useFormGroup } from '@idux/cdk'
|
|||
import { TableColumn } from '@idux/components/table'
|
||||
import { TablePagination } from '@idux/components/table/src/types'
|
||||
import Charts from '@/components/echarts/Charts.vue'
|
||||
import DisposeRecodeDetail from '@/pages/dispose-recode/DisposeRecodeDetail.vue'
|
||||
import DisposeRecodeApi from '@/pages/dispose-recode/dispose-recode-api.ts'
|
||||
import Times from '@/common/utils/times.ts'
|
||||
|
||||
const disposeRecodeDetail = ref<InstanceType<typeof DisposeRecodeDetail> | null>(null)
|
||||
const disposeRecode = ref<HTMLElement | undefined>(undefined)
|
||||
const chartOption = reactive<Echarts.Option>({
|
||||
aria: {
|
||||
enabled: true,
|
||||
|
@ -20,7 +25,7 @@ const chartOption = reactive<Echarts.Option>({
|
|||
},
|
||||
legend: {
|
||||
show: true,
|
||||
top: 0
|
||||
top: 0,
|
||||
},
|
||||
grid: {
|
||||
outerBounds: {
|
||||
|
@ -33,7 +38,7 @@ const chartOption = reactive<Echarts.Option>({
|
|||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ],
|
||||
data: [],
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
|
@ -47,67 +52,58 @@ const chartOption = reactive<Echarts.Option>({
|
|||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Direct1',
|
||||
type: 'bar',
|
||||
data: [ 10, 52, 200, 334, 390, 330, 220 ],
|
||||
},
|
||||
{
|
||||
name: 'Direct2',
|
||||
type: 'bar',
|
||||
data: [ 10, 52, 200, 334, 390, 330, 220 ]
|
||||
}
|
||||
]
|
||||
series: []
|
||||
})
|
||||
|
||||
interface Data {
|
||||
id: string
|
||||
pointName: string
|
||||
street: string
|
||||
microdistrict: string
|
||||
propertyManagement: string
|
||||
statusTxt: string
|
||||
status: 'ZhengChang' | 'FenZhengChang'
|
||||
}
|
||||
const formGroup = useFormGroup<DisposeRecodeTypes.SearchParam>({
|
||||
keywords: [ '' ],
|
||||
})
|
||||
|
||||
const formGroup = useFormGroup({})
|
||||
|
||||
const fullData: Data[] = []
|
||||
for (let index = 0; index < 10; index++) {
|
||||
fullData.push({
|
||||
id: index + '',
|
||||
pointName: `Edrward ${index}`,
|
||||
street: `Edrward ${index}`,
|
||||
microdistrict: `Edrward ${index}`,
|
||||
propertyManagement: `Edrward ${index}`,
|
||||
statusTxt: `Edrward ${index}`,
|
||||
status: index % 2 === 0 ? 'ZhengChang' : 'FenZhengChang',
|
||||
})
|
||||
}
|
||||
const data = ref(fullData)
|
||||
const datasource = ref<DisposeRecodeTypes.DisposeRecodeData[]>()
|
||||
const columns: TableColumn[] = [
|
||||
{
|
||||
title: '名称',
|
||||
dataKey: 'pointName',
|
||||
customCell: 'pointName'
|
||||
title: '来源地',
|
||||
dataKey: 'origin',
|
||||
},
|
||||
{
|
||||
title: '所属街道',
|
||||
dataKey: 'street',
|
||||
title: '清运公司',
|
||||
dataKey: 'clearingCompany',
|
||||
},
|
||||
{
|
||||
title: '所属小区',
|
||||
dataKey: 'microdistrict',
|
||||
title: '消纳场名称',
|
||||
dataKey: 'disposalSite',
|
||||
},
|
||||
{
|
||||
title: '所属物业',
|
||||
dataKey: 'propertyManagement'
|
||||
title: '车牌号',
|
||||
dataKey: 'licensePlate',
|
||||
},
|
||||
{
|
||||
title: '运营状态',
|
||||
dataKey: 'statusTxt',
|
||||
customCell: 'status',
|
||||
title: '联系人',
|
||||
dataKey: 'contact',
|
||||
},
|
||||
{
|
||||
title: '联系电话',
|
||||
dataKey: 'contactPhone',
|
||||
},
|
||||
{
|
||||
title: '进场磅重(吨)',
|
||||
dataKey: 'inWeight',
|
||||
},
|
||||
{
|
||||
title: '出场磅重(吨)',
|
||||
dataKey: 'outWeight',
|
||||
},
|
||||
{
|
||||
title: '净重(吨)',
|
||||
dataKey: 'suttleWeight',
|
||||
},
|
||||
{
|
||||
title: '进场时间',
|
||||
dataKey: 'inTime',
|
||||
},
|
||||
{
|
||||
title: '出场时间',
|
||||
dataKey: 'outTime',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
|
@ -128,17 +124,65 @@ const pagination = reactive<TablePagination>({
|
|||
pagination.pageSize = pageSize
|
||||
}
|
||||
})
|
||||
|
||||
const tableSpin = ref(false)
|
||||
|
||||
function searchHandler() {
|
||||
console.log('------', formGroup.getValue())
|
||||
tableSpin.value = true
|
||||
DisposeRecodeApi.paging({
|
||||
...formGroup.getValue(),
|
||||
current: pagination.pageIndex ?? 1,
|
||||
size: pagination.pageSize ?? 10,
|
||||
})
|
||||
.then(res => {
|
||||
pagination.pageIndex = res.data.current
|
||||
pagination.pageSize = res.data.size
|
||||
pagination.total = res.data.total
|
||||
datasource.value = res.data.records
|
||||
})
|
||||
.finally(() => {
|
||||
tableSpin.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function exportHandler() {
|
||||
DisposeRecodeApi.exportData([ '2025-01-01', '2025-01-31' ])
|
||||
}
|
||||
|
||||
const monthValue = ref<Date>(new Date())
|
||||
|
||||
function renderChart() {
|
||||
DisposeRecodeApi.statistics(Times.format(monthValue.value, Times.FMT.month))
|
||||
.then(res => {
|
||||
chartOption.xAxis[0].data = res.data.xAxis
|
||||
let series = []
|
||||
for (let seriesKey in res.data.series) {
|
||||
series.push({
|
||||
name: seriesKey,
|
||||
type: 'bar',
|
||||
data: res.data.series[seriesKey],
|
||||
})
|
||||
}
|
||||
chartOption.series = series
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
searchHandler()
|
||||
renderChart()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="dispose-recode">
|
||||
<div ref="disposeRecode" class="dispose-recode">
|
||||
<div class="title">垃圾处置记录</div>
|
||||
<div class="desc">管理和分析垃圾处置数据</div>
|
||||
<IxCard class="graph-card">
|
||||
<template #header>
|
||||
<div class="graph-tool">
|
||||
<div>垃圾处置量统计</div>
|
||||
<IxDatePicker type="month"/>
|
||||
<IxDatePicker v-model:value="monthValue" type="month" @change="renderChart"/>
|
||||
</div>
|
||||
</template>
|
||||
<Charts :option="chartOption"/>
|
||||
|
@ -147,31 +191,26 @@ const pagination = reactive<TablePagination>({
|
|||
<template #header>
|
||||
<div class="table-tool">
|
||||
<div>垃圾处置记录</div>
|
||||
<IxForm :control="formGroup" class="search-form" layout="inline">
|
||||
<IxForm :control="formGroup" class="search-form" layout="inline" @submit.prevent="searchHandler">
|
||||
<IxTooltip placement="top" title="输入内容回车搜索">
|
||||
<IxFormItem messageTooltip>
|
||||
<IxInput placeholder="请输入收纳点名称"/>
|
||||
<IxInput clearable control="keywords" placeholder="请输入" @clear="searchHandler"/>
|
||||
</IxFormItem>
|
||||
</IxTooltip>
|
||||
<IxFormItem messageTooltip>
|
||||
<IxInput placeholder="请输入收纳点名称"/>
|
||||
<IxButton icon="search" mode="primary" type="submit"/>
|
||||
</IxFormItem>
|
||||
</IxForm>
|
||||
<IxButton icon="download" mode="primary">导出</IxButton>
|
||||
<IxButton icon="download" mode="primary" @click="exportHandler">导出</IxButton>
|
||||
</div>
|
||||
</template>
|
||||
<IxTable :columns="columns" :dataSource="data" :pagination="pagination" autoHeight class="data-table" getKey="id">
|
||||
<template #pointName="{record}">
|
||||
<span style="color: #165DFF;border-radius: 100%;background-color: #165DFF1A;width: 2.25rem;height: 2.25rem;display: inline-flex;justify-content: center;align-items: center;margin-right: 0.5rem"><i class="iconfont icon-mapmarker" style="display: block"></i></span>
|
||||
<span>{{ record.pointName }}</span>
|
||||
</template>
|
||||
<template #action>
|
||||
<IxButton class="detail-btn" icon="eye" mode="text">查看</IxButton>
|
||||
</template>
|
||||
<template #status="{record}">
|
||||
<IxTag v-if="record.status === 'ZhengChang'" status="success">{{ record.statusTxt }}</IxTag>
|
||||
<IxTag v-else status="error">{{ record.statusTxt }}</IxTag>
|
||||
<IxTable :columns="columns" :dataSource="datasource" :pagination="pagination" autoHeight class="data-table" getKey="id">
|
||||
<template #action="{record}">
|
||||
<IxButton class="detail-btn" icon="eye" mode="text" @click="disposeRecodeDetail?.open(record)">查看</IxButton>
|
||||
</template>
|
||||
</IxTable>
|
||||
</IxCard>
|
||||
<DisposeRecodeDetail ref="disposeRecodeDetail" :container="disposeRecode"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -179,7 +218,7 @@ const pagination = reactive<TablePagination>({
|
|||
.dispose-recode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
height: 150%;
|
||||
width: 100%;
|
||||
|
||||
.title {
|
||||
|
@ -256,8 +295,12 @@ const pagination = reactive<TablePagination>({
|
|||
.search-form {
|
||||
flex 6
|
||||
|
||||
:deep(.ix-form-item) {
|
||||
flex 2
|
||||
:deep(.ix-form-item):nth-child(1) {
|
||||
flex 7
|
||||
}
|
||||
|
||||
:deep(.ix-form-item):nth-child(2) {
|
||||
flex 1
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
<script lang="ts" setup>
|
||||
let props = defineProps<{
|
||||
container?: HTMLElement;
|
||||
}>()
|
||||
const show = ref(false)
|
||||
const ins = ref<HTMLElement | null>(null)
|
||||
const data = reactive<DisposeRecodeTypes.DisposeRecodeData>({
|
||||
id: '',
|
||||
origin: '',
|
||||
clearingCompany: '',
|
||||
licensePlate: '',
|
||||
contact: '',
|
||||
contactPhone: '',
|
||||
inWeight: '',
|
||||
outWeight: '',
|
||||
suttleWeight: '',
|
||||
inTime: '',
|
||||
outTime: '',
|
||||
disposalSite: '',
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
console.log(ins)
|
||||
let container = props.container
|
||||
if (container) {
|
||||
container.style.position = 'relative'
|
||||
for (let child of container.children) {
|
||||
console.log(child)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
open(detail: DisposeRecodeTypes.DisposeRecodeData) {
|
||||
Object.assign(data, detail)
|
||||
show.value = true
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<IxModal ref="ins" v-model:visible="show" :container="container" :mask="false" cancel-text="关闭" class="dispose-recode-detail" draggable header="详情" maskClosable type="default" width="40rem">
|
||||
<p class="detail-item"><span>来源地:</span><span>{{ data.origin }}</span></p>
|
||||
<p class="detail-item"><span>清运公司:</span><span>{{ data.clearingCompany }}</span></p>
|
||||
<p class="detail-item"><span>车牌号:</span><span>{{ data.licensePlate }}</span></p>
|
||||
<p class="detail-item"><span>联系人:</span><span>{{ data.contact }}</span></p>
|
||||
<p class="detail-item"><span>联系电话:</span><span>{{ data.contactPhone }}</span></p>
|
||||
<p class="detail-item"><span>进场磅重(吨):</span><span>{{ data.inWeight }}</span></p>
|
||||
<p class="detail-item"><span>出场磅重(吨):</span><span>{{ data.outWeight }}</span></p>
|
||||
<p class="detail-item"><span>净重(吨):</span><span>{{ data.suttleWeight }}</span></p>
|
||||
<p class="detail-item"><span>进场时间:</span><span>{{ data.inTime }}</span></p>
|
||||
<p class="detail-item"><span>出场时间:</span><span>{{ data.outTime }}</span></p>
|
||||
<p class="detail-item"><span>消纳场名称:</span><span>{{ data.disposalSite }}</span></p>
|
||||
<template #footer="{ cancel:_, ok }">
|
||||
<IxButton mode="primary" @click="ok">确定</IxButton>
|
||||
</template>
|
||||
</IxModal>
|
||||
</template>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.dispose-recode-detail .detail-item:not(:last-child) {
|
||||
border-bottom: 1px #E5E7EB dashed;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
:deep(.ix-modal-wrapper),
|
||||
:deep(.ix-mask) {
|
||||
position absolute
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
display flex
|
||||
justify-content start
|
||||
align-items center
|
||||
|
||||
span:nth-child(1) {
|
||||
flex 10
|
||||
font-weight bold
|
||||
}
|
||||
|
||||
span:nth-child(2) {
|
||||
flex 14
|
||||
text-align end
|
||||
padding-right 10%
|
||||
}
|
||||
|
||||
|
||||
span {
|
||||
display inline-block
|
||||
color #1D2129
|
||||
font-size 1.25rem
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,32 @@
|
|||
import {
|
||||
download,
|
||||
get,
|
||||
post
|
||||
} from '@/common/utils/http-util.ts'
|
||||
|
||||
export default {
|
||||
paging(data: DisposeRecodeTypes.SearchParam & G.PageParam) {
|
||||
return get<G.PageResult<DisposeRecodeTypes.DisposeRecodeData>>('/dispose_record/paging', data)
|
||||
},
|
||||
list(pid: string | null = null) {
|
||||
return get<DisposeRecodeTypes.DisposeRecodeData[]>('/dispose_record/list', {pid: pid})
|
||||
},
|
||||
detail(id: string) {
|
||||
return get<DisposeRecodeTypes.DisposeRecodeData>('/dispose_record/detail', {id})
|
||||
},
|
||||
add(data: DisposeRecodeTypes.DisposeRecodeData) {
|
||||
return post('/dispose_record/add', data)
|
||||
},
|
||||
modify(data: DisposeRecodeTypes.DisposeRecodeData) {
|
||||
return post('/dispose_record/modify', data)
|
||||
},
|
||||
del(ids: string[]) {
|
||||
return post('/dispose_record/del', ids)
|
||||
},
|
||||
exportData(date: string[]) {
|
||||
return download('/dispose_record/export', {date})
|
||||
},
|
||||
statistics(date: string) {
|
||||
return get<DisposeRecodeTypes.StatisticsResult>('/dispose_record/statistics', {date})
|
||||
},
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
export {}
|
||||
declare global {
|
||||
namespace DisposeRecodeTypes {
|
||||
interface DisposeRecodeData {
|
||||
id: string
|
||||
origin: string
|
||||
clearingCompany: string
|
||||
licensePlate: string
|
||||
contact: string
|
||||
contactPhone: string
|
||||
inWeight: string
|
||||
outWeight: string
|
||||
suttleWeight: string
|
||||
inTime: string
|
||||
outTime: string
|
||||
disposalSite: string
|
||||
}
|
||||
|
||||
interface SearchParam {
|
||||
keywords: string
|
||||
}
|
||||
|
||||
interface StatisticsResult {
|
||||
xAxis: string[]
|
||||
series: {
|
||||
[key: string]: number[]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,37 +3,35 @@ import { SelectData } from '@idux/components/select/src/types'
|
|||
import { useFormGroup } from '@idux/cdk'
|
||||
import { TableColumn } from '@idux/components/table'
|
||||
import { TablePagination } from '@idux/components/table/src/types'
|
||||
import CreateTsp from '@/pages/tsp/create-tsp.vue'
|
||||
import TspApi from '@/pages/tsp/tsp-api.ts'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const createTsp = ref<InstanceType<typeof CreateTsp> | null>(null)
|
||||
const dataSource: SelectData[] = [
|
||||
{key: '', label: '所有'},
|
||||
{key: 'ZhengChang', label: '正常运营'},
|
||||
{key: 'FenZhengChang', label: '非正常运营'},
|
||||
]
|
||||
|
||||
interface Data {
|
||||
id: string
|
||||
pointName: string
|
||||
street: string
|
||||
microdistrict: string
|
||||
propertyManagement: string
|
||||
statusTxt: string
|
||||
status: 'ZhengChang' | 'FenZhengChang'
|
||||
}
|
||||
const pagination = reactive<TablePagination>({
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
size: 'sm',
|
||||
showTotal: true,
|
||||
onChange(pageIndex: number, pageSize: number) {
|
||||
console.log('------', pageIndex, pageSize)
|
||||
pagination.pageIndex = pageIndex
|
||||
pagination.pageSize = pageSize
|
||||
}
|
||||
})
|
||||
|
||||
const formGroup = useFormGroup({})
|
||||
|
||||
const fullData: Data[] = []
|
||||
for (let index = 0; index < 10; index++) {
|
||||
fullData.push({
|
||||
id: index + '',
|
||||
pointName: `Edrward ${index}`,
|
||||
street: `Edrward ${index}`,
|
||||
microdistrict: `Edrward ${index}`,
|
||||
propertyManagement: `Edrward ${index}`,
|
||||
statusTxt: `Edrward ${index}`,
|
||||
status: index % 2 === 0 ? 'ZhengChang' : 'FenZhengChang',
|
||||
})
|
||||
}
|
||||
const data = ref(fullData)
|
||||
const formGroup = useFormGroup<TspTypes.SearchParam>({
|
||||
pointName: [ '' ],
|
||||
status: [ '' ],
|
||||
})
|
||||
const datasource = ref<TspTypes.TspData[]>()
|
||||
const columns: TableColumn[] = [
|
||||
{
|
||||
title: '名称',
|
||||
|
@ -42,7 +40,7 @@ const columns: TableColumn[] = [
|
|||
},
|
||||
{
|
||||
title: '所属街道',
|
||||
dataKey: 'street',
|
||||
dataKey: 'streetName',
|
||||
},
|
||||
{
|
||||
title: '所属小区',
|
||||
|
@ -63,18 +61,40 @@ const columns: TableColumn[] = [
|
|||
customCell: 'action',
|
||||
}
|
||||
]
|
||||
const tableSpin = ref(false)
|
||||
const statisticsResult = reactive<TspTypes.StatisticsResult>({
|
||||
totalCount: 0,
|
||||
totalCountGrowthRate: 0,
|
||||
onlineCount: 0,
|
||||
onlineCountGrowthRate: 0,
|
||||
offlineCount: 0,
|
||||
offlineCountGrowthRate: 0,
|
||||
})
|
||||
|
||||
const pagination = reactive<TablePagination>({
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
total: 100,
|
||||
size: 'sm',
|
||||
showTotal: true,
|
||||
onChange(pageIndex: number, pageSize: number) {
|
||||
console.log('------', pageIndex, pageSize)
|
||||
pagination.pageIndex = pageIndex
|
||||
pagination.pageSize = pageSize
|
||||
}
|
||||
function searchHandler() {
|
||||
tableSpin.value = true
|
||||
TspApi.paging({
|
||||
...formGroup.getValue(),
|
||||
current: pagination.pageIndex ?? 1,
|
||||
size: pagination.pageSize ?? 10,
|
||||
})
|
||||
.then(res => {
|
||||
pagination.pageIndex = res.data.current
|
||||
pagination.pageSize = res.data.size
|
||||
pagination.total = res.data.total
|
||||
datasource.value = res.data.records
|
||||
})
|
||||
.finally(() => {
|
||||
tableSpin.value = false
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
searchHandler()
|
||||
TspApi.statistics()
|
||||
.then(res => {
|
||||
Object.assign(statisticsResult, res.data)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
|
@ -85,24 +105,24 @@ const pagination = reactive<TablePagination>({
|
|||
<IxCard>
|
||||
<div>
|
||||
<div>收纳点总数</div>
|
||||
<div>24</div>
|
||||
<div><i class="iconfont icon-arrow-up"></i>较上月增长 12%</div>
|
||||
<div>{{ statisticsResult.totalCount }}</div>
|
||||
<div><i class="iconfont icon-arrow-up"></i>较上月增长 {{ statisticsResult.totalCountGrowthRate }}%</div>
|
||||
</div>
|
||||
<Iconfont name="map-pin" wrapper/>
|
||||
</IxCard>
|
||||
<IxCard>
|
||||
<div>
|
||||
<div>正常运营数量</div>
|
||||
<div>24</div>
|
||||
<div><i class="iconfont icon-arrow-up"></i>较上月增长 8%</div>
|
||||
<div>{{ statisticsResult.onlineCount }}</div>
|
||||
<div><i class="iconfont icon-arrow-up"></i>较上月增长 {{ statisticsResult.onlineCountGrowthRate }}%</div>
|
||||
</div>
|
||||
<Iconfont name="check-circle-fill" wrapper/>
|
||||
</IxCard>
|
||||
<IxCard>
|
||||
<div>
|
||||
<div>非正常运营数量</div>
|
||||
<div>24</div>
|
||||
<div><i class="iconfont icon-arrow-up"></i>较上月增长 2%</div>
|
||||
<div>{{ statisticsResult.offlineCount }}</div>
|
||||
<div><i class="iconfont icon-arrow-up"></i>较上月增长 {{ statisticsResult.offlineCountGrowthRate }}%</div>
|
||||
</div>
|
||||
<Iconfont name="exclamationcircle-f" wrapper/>
|
||||
</IxCard>
|
||||
|
@ -111,18 +131,25 @@ const pagination = reactive<TablePagination>({
|
|||
<template #header>
|
||||
<div class="table-tool">
|
||||
<div>收纳点列表</div>
|
||||
<IxForm :control="formGroup" class="search-form" layout="inline">
|
||||
<IxForm :control="formGroup" class="search-form" layout="inline" @submit.prevent="searchHandler">
|
||||
<IxTooltip placement="top" title="输入内容回车搜索">
|
||||
<IxFormItem messageTooltip>
|
||||
<IxInput placeholder="请输入收纳点名称"/>
|
||||
<IxInput clearable control="pointName" placeholder="请输入收纳点名称" @clear="searchHandler"/>
|
||||
</IxFormItem>
|
||||
</IxTooltip>
|
||||
<IxFormItem messageTooltip>
|
||||
<IxSelect :dataSource="dataSource" control="status" @change="searchHandler"/>
|
||||
</IxFormItem>
|
||||
<IxFormItem messageTooltip>
|
||||
<IxSelect :dataSource="dataSource"/>
|
||||
<IxButton icon="search" mode="primary" type="submit"/>
|
||||
</IxFormItem>
|
||||
<IxButton icon="plus" mode="primary" type="submit">添加收纳点</IxButton>
|
||||
</IxForm>
|
||||
<IxButton icon="plus" mode="primary" @click="createTsp?.open()">添加收纳点</IxButton>
|
||||
</div>
|
||||
</template>
|
||||
<IxTable :columns="columns" :dataSource="data" :pagination="pagination" autoHeight class="data-table" getKey="id">
|
||||
<IxTable :columns="columns"
|
||||
:dataSource="datasource"
|
||||
:pagination="pagination" :spin="tableSpin" autoHeight class="data-table" getKey="id">
|
||||
<template #pointName="{record}">
|
||||
<Iconfont name="mapmarker" wrapper/>
|
||||
<span>{{ record.pointName }}</span>
|
||||
|
@ -136,6 +163,7 @@ const pagination = reactive<TablePagination>({
|
|||
</template>
|
||||
</IxTable>
|
||||
</IxCard>
|
||||
<CreateTsp ref="createTsp"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -294,9 +322,16 @@ const pagination = reactive<TablePagination>({
|
|||
}
|
||||
|
||||
.search-form {
|
||||
:deep(.ix-form-item) {
|
||||
flex 2
|
||||
:deep(.ix-form-item):nth-child(1) {
|
||||
flex 5
|
||||
}
|
||||
|
||||
:deep(.ix-form-item):nth-child(2) {
|
||||
flex 2
|
||||
}
|
||||
|
||||
:deep(.ix-form-item):nth-child(3) {
|
||||
flex 1
|
||||
}
|
||||
|
||||
:deep(.ix-button ) {
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
useFormGroup,
|
||||
Validators
|
||||
} from '@idux/cdk'
|
||||
import Toast from '@/components/toast'
|
||||
import TspApi from '@/pages/tsp/tsp-api.ts'
|
||||
|
||||
const show = ref(false)
|
||||
const formGroup = useFormGroup<TspTypes.AddParam>({
|
||||
pointName: [ undefined, Validators.required ],
|
||||
streetName: [ undefined, Validators.required ],
|
||||
microdistrict: [ undefined, Validators.required ],
|
||||
propertyManagement: [ undefined, Validators.required ],
|
||||
videoUrl: [ undefined, Validators.required ],
|
||||
})
|
||||
|
||||
const gutter = [ 40, 0 ]
|
||||
|
||||
function submit() {
|
||||
if (formGroup.valid.value) {
|
||||
TspApi.add({...formGroup.getValue(), status: 'ZhengChang'})
|
||||
.then(_ => {
|
||||
Toast.success('添加成功')
|
||||
formGroup.reset()
|
||||
})
|
||||
} else {
|
||||
formGroup.markAsDirty()
|
||||
Toast.error('请填写完整信息')
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open() {
|
||||
show.value = true
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<IxModal v-model:visible="show" cancel-text="取消" header="添加收纳点" ok-text="提交" type="default" width="40rem" @cancel="formGroup.reset()" @close="formGroup.reset()" @ok="submit">
|
||||
<IxForm :colonless="false" :control="formGroup" :control-col="{span: 19}" :label-col="5" label-align="end" style="height: 23.4rem">
|
||||
<IxFormItem :gutter="gutter" label="收纳点名称" messageTooltip>
|
||||
<IxInput control="pointName" placeholder="请输入收纳点名称"/>
|
||||
</IxFormItem>
|
||||
<IxFormItem :gutter="gutter" label="所属街道" messageTooltip>
|
||||
<IxInput control="streetName" placeholder="请输入街道名称"/>
|
||||
</IxFormItem>
|
||||
<IxFormItem :gutter="gutter" label="所属小区" messageTooltip>
|
||||
<IxInput control="microdistrict" placeholder="请输入小区名称"/>
|
||||
</IxFormItem>
|
||||
<IxFormItem :gutter="gutter" label="所属物业" messageTooltip>
|
||||
<IxInput control="propertyManagement" placeholder="请输入物业名称"/>
|
||||
</IxFormItem>
|
||||
<IxFormItem :gutter="gutter" label="视频地址" messageTooltip>
|
||||
<IxInput control="videoUrl" placeholder="请输入视频地址"/>
|
||||
</IxFormItem>
|
||||
</IxForm>
|
||||
</IxModal>
|
||||
</template>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,28 @@
|
|||
import {
|
||||
get,
|
||||
post
|
||||
} from '@/common/utils/http-util.ts'
|
||||
|
||||
export default {
|
||||
paging(data: TspTypes.SearchParam & G.PageParam) {
|
||||
return get<G.PageResult<TspTypes.TspData>>('/temp_storage_point/paging', data)
|
||||
},
|
||||
list(pid: string | null = null) {
|
||||
return get<TspTypes.TspData[]>('/temp_storage_point/list', {pid: pid})
|
||||
},
|
||||
detail(id: string) {
|
||||
return get<TspTypes.TspData>('/temp_storage_point/detail', {id})
|
||||
},
|
||||
add(data: TspTypes.AddParam) {
|
||||
return post('/temp_storage_point/add', data)
|
||||
},
|
||||
modify(data: TspTypes.TspData) {
|
||||
return post('/temp_storage_point/modify', data)
|
||||
},
|
||||
del(ids: string[]) {
|
||||
return post('/temp_storage_point/del', ids)
|
||||
},
|
||||
statistics() {
|
||||
return get<TspTypes.StatisticsResult>('/temp_storage_point/statistics')
|
||||
},
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
export {}
|
||||
declare global {
|
||||
namespace TspTypes {
|
||||
interface TspData {
|
||||
id: string
|
||||
pointName: string
|
||||
streetName: string
|
||||
microdistrict: string
|
||||
propertyManagement: string
|
||||
status: 'ZhengChang' | 'FenZhengChang'
|
||||
}
|
||||
|
||||
interface AddParam {
|
||||
pointName?: string
|
||||
streetName?: string
|
||||
microdistrict?: string
|
||||
propertyManagement?: string
|
||||
status?: 'ZhengChang' | 'FenZhengChang'
|
||||
videoUrl?: string
|
||||
}
|
||||
|
||||
interface SearchParam {
|
||||
pointName: string
|
||||
status: 'ZhengChang' | 'FenZhengChang' | ''
|
||||
}
|
||||
|
||||
interface StatisticsResult {
|
||||
totalCount: number
|
||||
totalCountGrowthRate: number
|
||||
onlineCount: number
|
||||
onlineCountGrowthRate: number
|
||||
offlineCount: number
|
||||
offlineCountGrowthRate: number
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue