This commit is contained in:
messi
2024-08-21 12:55:18 +08:00
parent b5e5a19b69
commit 26a8ce42ab
10 changed files with 934 additions and 63 deletions

View File

@@ -123,8 +123,8 @@
const companyLogo = localStorage.getItem('CompanyLogo');
const shortName = localStorage.getItem('ShortName');
const logo = ref<any>('/assets/logo.svg');
if (tenantName) {
projectName.value = String(tenantName);
if (tenantName!=null) {
//projectName.value = String(tenantName);
}
if (companyLogo) {
logo.value = companyLogo;

View File

@@ -2,7 +2,7 @@
<template>
<a-row :gutter="16">
<a-col
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 6 }"
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 8}"
>
<a-card class="analysis-chart-card" :bordered="false">
<div class="ele-text-secondary ele-cell">
@@ -13,25 +13,18 @@
</div>
<h1 class="analysis-chart-card-num">¥ 126,560</h1>
<div class="analysis-chart-card-content" style="padding-top: 16px">
<a-space size="middle">
<span class="analysis-trend-text">
周同比12% <caret-up-outlined class="ele-text-danger" />
</span>
<span class="analysis-trend-text">
日同比11% <caret-down-outlined class="ele-text-success" />
</span>
</a-space>
</div>
<a-divider />
<div>日销售额 12,423</div>
</a-card>
</a-col>
<a-col
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 6 }"
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 8 }"
>
<a-card class="analysis-chart-card" :bordered="false">
<div class="ele-text-secondary ele-cell">
<div class="ele-cell-content">访问量</div>
<div class="ele-cell-content">总用户</div>
<ele-tag color="red"></ele-tag>
</div>
<h1 class="analysis-chart-card-num">8,846</h1>
@@ -41,16 +34,16 @@
style="height: 40px"
/>
<a-divider />
<div>访问量 1,234</div>
<div>新增用户 1,234</div>
</a-card>
</a-col>
<a-col
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 6 }"
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 8 }"
>
<a-card class="analysis-chart-card" :bordered="false">
<div class="ele-text-secondary ele-cell">
<div class="ele-cell-content">支付笔数</div>
<ele-tag color="blue"></ele-tag>
<div class="ele-cell-content">支付笔数</div>
<ele-tag color="blue"></ele-tag>
</div>
<h1 class="analysis-chart-card-num">6,560</h1>
<v-chart
@@ -59,37 +52,11 @@
style="height: 40px"
/>
<a-divider />
<div>转化率 60%</div>
</a-card>
</a-col>
<a-col
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 6 }"
>
<a-card class="analysis-chart-card" :bordered="false">
<div class="ele-text-secondary ele-cell">
<div class="ele-cell-content">活动运营效果</div>
<ele-tag color="green"></ele-tag>
</div>
<h1 class="analysis-chart-card-num">78%</h1>
<div class="analysis-chart-card-content" style="padding-top: 16px">
<a-progress
:percent="78"
:show-info="false"
stroke-color="#13c2c2"
status="active"
/>
</div>
<a-divider />
<a-space size="middle">
<span class="analysis-trend-text">
周同比12% <caret-up-outlined class="ele-text-danger" />
</span>
<span class="analysis-trend-text">
日同比11% <caret-down-outlined class="ele-text-success" />
</span>
</a-space>
<div>日新增订单 1,234</div>
</a-card>
</a-col>
</a-row>
</template>

View File

@@ -2,22 +2,7 @@
<div class="ele-body ele-body-card">
<statistics-card />
<sale-card />
<a-row :gutter="16">
<a-col
v-bind="
styleResponsive ? { lg: 16, md: 14, sm: 24, xs: 24 } : { span: 16 }
"
>
<visit-hour />
</a-col>
<a-col
v-bind="
styleResponsive ? { lg: 8, md: 10, sm: 24, xs: 24 } : { span: 8 }
"
>
<hot-search />
</a-col>
</a-row>
</div>
</template>

View File

@@ -0,0 +1,72 @@
<template>
<a-card :bordered="false" title="热门搜索">
<v-chart
ref="hotSearchChartRef"
:option="hotSearchChartOption"
style="height: 330px"
/>
</a-card>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { message } from 'ant-design-vue/es';
import { use } from 'echarts/core';
import type { EChartsCoreOption } from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import { LineChart, BarChart } from 'echarts/charts';
import { GridComponent, TooltipComponent } from 'echarts/components';
import VChart from 'vue-echarts';
import 'echarts-wordcloud';
import { wordCloudColor } from 'ele-admin-pro/es';
import { getWordCloudList } from '@/api/dashboard/analysis';
import useEcharts from '@/utils/use-echarts';
use([CanvasRenderer, LineChart, BarChart, GridComponent, TooltipComponent]);
//
const hotSearchChartRef = ref<InstanceType<typeof VChart> | null>(null);
useEcharts([hotSearchChartRef]);
// 词云图表配置
const hotSearchChartOption: EChartsCoreOption = reactive({});
/* 获取词云数据 */
const getWordCloudData = () => {
getWordCloudList()
.then((data) => {
Object.assign(hotSearchChartOption, {
tooltip: {
show: true,
confine: true,
borderWidth: 1
},
series: [
{
type: 'wordCloud',
width: '100%',
height: '100%',
sizeRange: [12, 24],
gridSize: 6,
textStyle: {
color: wordCloudColor
},
emphasis: {
textStyle: {
shadowBlur: 8,
shadowColor: 'rgba(0, 0, 0, .15)'
}
},
data: data
}
]
});
})
.catch((e) => {
message.error(e.message);
});
};
getWordCloudData();
</script>

View File

@@ -0,0 +1,248 @@
<template>
<a-card :bordered="false" :body-style="{ padding: 0 }">
<a-tabs
size="large"
v-model:activeKey="saleSearch.type"
class="monitor-card-tabs"
@change="onSaleTypeChange"
>
<a-tab-pane tab="商品销售排行(全门店)" key="saleroom" />
<a-tab-pane tab="用户消费排行(全门店)" />
<template #rightExtra>
<a-space
size="middle"
:class="[
'analysis-tabs-extra',
{ 'hidden-lg-and-down': styleResponsive }
]"
>
<a-radio-group v-model:value="saleSearch.dateType">
<a-radio-button value="1">今天</a-radio-button>
<a-radio-button value="2">本周</a-radio-button>
<a-radio-button value="3">本月</a-radio-button>
<a-radio-button value="4">本年</a-radio-button>
</a-radio-group>
<div style="width: 300px">
<a-range-picker
value-format="YYYY-MM-DD"
v-model:value="saleSearch.datetime"
/>
</div>
</a-space>
</template>
</a-tabs>
<div style="padding-bottom: 10px">
<a-row :gutter="16">
<a-col
v-bind="
styleResponsive ? { lg: 17, md: 15, sm: 24, xs: 24 } : { span: 17 }
"
>
<div v-if="saleSearch.type === 'saleroom'" class="demo-monitor-title">
销售量趋势
</div>
<div v-else class="demo-monitor-title">访问量趋势</div>
<v-chart
ref="saleChartRef"
:option="saleChartOption"
style="height: 320px"
/>
</a-col>
<a-col
v-bind="
styleResponsive ? { lg: 7, md: 9, sm: 24, xs: 24 } : { span: 7 }
"
>
<div v-if="saleSearch.type === 'saleroom'">
<div class="demo-monitor-title">门店销售额排名</div>
<div
v-for="(item, index) in saleroomRankData"
:key="index"
class="demo-monitor-rank-item ele-cell"
>
<ele-tag
shape="circle"
:color="index < 3 ? '#314659' : ''"
style="border: none"
>
{{ index + 1 }}
</ele-tag>
<div class="ele-cell-content ele-elip">{{ item.name }}</div>
<div class="ele-text-secondary">{{ item.value }}</div>
</div>
</div>
<div v-else>
<div class="demo-monitor-title">门店访问量排名</div>
<div
v-for="(item, index) in visitsRankData"
:key="index"
class="demo-monitor-rank-item ele-cell"
>
<ele-tag
shape="circle"
:color="index < 3 ? '#314659' : ''"
style="border: none"
>
{{ index + 1 }}
</ele-tag>
<div class="ele-cell-content ele-elip">{{ item.name }}</div>
<div class="ele-text-secondary">{{ item.value }}</div>
</div>
</div>
</a-col>
</a-row>
</div>
</a-card>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { message } from 'ant-design-vue/es';
import { use } from 'echarts/core';
import type { EChartsCoreOption } from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import { BarChart } from 'echarts/charts';
import { GridComponent, TooltipComponent } from 'echarts/components';
import VChart from 'vue-echarts';
import { storeToRefs } from 'pinia';
import { useThemeStore } from '@/store/modules/theme';
import { getSaleroomList } from '@/api/dashboard/analysis';
import type { SaleroomData } from '@/api/dashboard/analysis/model';
import useEcharts from '@/utils/use-echarts';
use([CanvasRenderer, BarChart, GridComponent, TooltipComponent]);
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
//
const saleChartRef = ref<InstanceType<typeof VChart> | null>(null);
useEcharts([saleChartRef]);
// 销售额柱状图配置
const saleChartOption: EChartsCoreOption = reactive({});
// 门店销售排名数据
const saleroomRankData = ref([
{ name: '工专路 1 号店', value: '323,234' },
{ name: '工专路 2 号店', value: '323,234' },
{ name: '工专路 3 号店', value: '323,234' },
{ name: '工专路 4 号店', value: '323,234' },
{ name: '工专路 5 号店', value: '323,234' },
{ name: '工专路 6 号店', value: '323,234' },
{ name: '工专路 7 号店', value: '323,234' }
]);
// 门店访问排名数据
const visitsRankData = ref([
{ name: '工专路 1 号店', value: '323,234' },
{ name: '工专路 2 号店', value: '323,234' },
{ name: '工专路 3 号店', value: '323,234' },
{ name: '工专路 4 号店', value: '323,234' },
{ name: '工专路 5 号店', value: '323,234' },
{ name: '工专路 6 号店', value: '323,234' },
{ name: '工专路 7 号店', value: '323,234' }
]);
// 销售量趋势数据
const saleroomData1 = ref<SaleroomData[]>([]);
// 访问量趋势数据
const saleroomData2 = ref<SaleroomData[]>([]);
interface SaleSearchType {
type: string;
dateType: string;
datetime: [string, string];
}
// 销售量搜索参数
const saleSearch = reactive<SaleSearchType>({
type: 'saleroom',
dateType: '1',
datetime: ['2022-01-08', '2022-02-12']
});
/* 获取销售量数据 */
const getSaleroomData = () => {
getSaleroomList()
.then((data) => {
saleroomData1.value = data.list1;
saleroomData2.value = data.list2;
onSaleTypeChange();
})
.catch((e) => {
message.error(e.message);
});
};
/* 销售量tab选择改变事件 */
const onSaleTypeChange = () => {
if (saleSearch.type === 'saleroom') {
Object.assign(saleChartOption, {
tooltip: {
trigger: 'axis'
},
xAxis: [
{
type: 'category',
data: saleroomData1.value.map((d) => d.month)
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
type: 'bar',
data: saleroomData1.value.map((d) => d.value)
}
]
});
} else {
Object.assign(saleChartOption, {
tooltip: {
trigger: 'axis'
},
xAxis: [
{
type: 'category',
data: saleroomData2.value.map((d) => d.month)
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
type: 'bar',
data: saleroomData2.value.map((d) => d.value)
}
]
});
}
};
getSaleroomData();
</script>
<style lang="less" scoped>
.monitor-card-tabs :deep(.ant-tabs-nav) {
padding: 0 16px;
}
.demo-monitor-title {
padding: 6px 20px;
}
.demo-monitor-rank-item {
padding: 0 20px;
margin-top: 18px;
}
</style>

View File

@@ -0,0 +1,236 @@
<!-- 统计卡片 -->
<template>
<a-row :gutter="16" v-if="data">
<a-col
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 6 }"
>
<a-card class="analysis-chart-card" :bordered="false">
<div class="ele-text-secondary ele-cell">
<div class="ele-cell-content">总销售额</div>
<a-tooltip title="指标说明">
<ele-tag color="green">全门店</ele-tag>
</a-tooltip>
</div>
<h1 class="analysis-chart-card-num"
>¥ {{ formatNumber(data[0].totalPrice) }}</h1
>
<a-divider />
<div class="flex justify-between">
<span>本月订单数</span>
<span>{{ data.todayOrders }}</span>
</div>
</a-card>
</a-col>
<a-col
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 6 }"
>
<a-card class="analysis-chart-card" :bordered="false">
<div class="ele-text-secondary ele-cell">
<div class="ele-cell-content">订单总数</div>
<ele-tag color="green">全门店</ele-tag>
</div>
<h1 class="analysis-chart-card-num">{{ data.totalOrders }}</h1>
<a-divider />
<div class="flex justify-between">
<span>昨日订单数</span>
<span>{{ 634 }}</span>
</div>
</a-card>
</a-col>
<a-col
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 6 }"
>
<a-card class="analysis-chart-card" :bordered="false">
<div class="ele-text-secondary ele-cell">
<div class="ele-cell-content">会员总数</div>
<ele-tag color="blue">全门店</ele-tag>
</div>
<h1 class="analysis-chart-card-num">16,560</h1>
<a-divider />
<div class="flex justify-between">
<span>今日订单数</span>
<span>1</span>
</div>
</a-card>
</a-col>
<a-col
v-bind="styleResponsive ? { lg: 6, md: 12, sm: 24, xs: 24 } : { span: 6 }"
>
<a-card class="analysis-chart-card" :bordered="false">
<div class="ele-text-secondary ele-cell">
<div class="ele-cell-content">商品总数</div>
<ele-tag color="green">全门店</ele-tag>
</div>
<h1 class="analysis-chart-card-num">78</h1>
<!-- <div class="analysis-chart-card-content" style="padding-top: 16px">-->
<!-- </div>-->
<a-divider />
<div class="flex justify-between">
<span>今日订单数</span>
<span>1</span>
</div>
</a-card>
</a-col>
</a-row>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { message } from 'ant-design-vue/es';
import {
QuestionCircleOutlined,
CaretUpOutlined,
CaretDownOutlined
} from '@ant-design/icons-vue';
import { use } from 'echarts/core';
import type { EChartsCoreOption } from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import { LineChart, BarChart } from 'echarts/charts';
import { GridComponent, TooltipComponent } from 'echarts/components';
import VChart from 'vue-echarts';
import { storeToRefs } from 'pinia';
import { formatNumber } from 'ele-admin-pro/es';
import { useThemeStore } from '@/store/modules/theme';
import { getPayNumList } from '@/api/dashboard/analysis';
import useEcharts from '@/utils/use-echarts';
import { Count } from '@/api/shop/count/model';
use([CanvasRenderer, LineChart, BarChart, GridComponent, TooltipComponent]);
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: Count | null;
}>();
//
const visitChartRef = ref<InstanceType<typeof VChart> | null>(null);
const payNumChartRef = ref<InstanceType<typeof VChart> | null>(null);
useEcharts([visitChartRef, payNumChartRef]);
// 访问量折线图配置
const visitChartOption: EChartsCoreOption = reactive({});
// 支付笔数柱状图配置
const payNumChartOption: EChartsCoreOption = reactive({});
/* 获取支付笔数数据 */
const getPayNumData = () => {
getPayNumList()
.then((data) => {
Object.assign(visitChartOption, {
color: '#975fe5',
tooltip: {
trigger: 'axis',
formatter:
'<i class="ele-chart-dot" style="background: #975fe5;"></i>{b0}: {c0}'
},
grid: {
top: 10,
bottom: 0,
left: 0,
right: 0
},
xAxis: [
{
show: false,
type: 'category',
boundaryGap: false,
data: data.map((d) => d.date)
}
],
yAxis: [
{
show: false,
type: 'value',
splitLine: {
show: false
}
}
],
series: [
{
type: 'line',
smooth: true,
symbol: 'none',
areaStyle: {
opacity: 0.5
},
data: data.map((d) => d.value)
}
]
});
Object.assign(payNumChartOption, {
tooltip: {
trigger: 'axis',
formatter:
'<i class="ele-chart-dot" style="background: #5b8ff9;"></i>{b0}: {c0}'
},
grid: {
top: 10,
bottom: 0,
left: 0,
right: 0
},
xAxis: [
{
show: false,
type: 'category',
data: data.map((d) => d.date)
}
],
yAxis: [
{
show: false,
type: 'value',
splitLine: {
show: false
}
}
],
series: [
{
type: 'bar',
data: data.map((d) => d.value)
}
]
});
})
.catch((e) => {
message.error(e.message);
});
};
getPayNumData();
</script>
<style lang="less" scoped>
.analysis-chart-card {
:deep(.ant-card-body) {
padding: 16px 22px 12px 22px;
}
:deep(.ant-divider) {
margin: 12px 0;
}
}
.analysis-chart-card-num {
font-size: 30px;
}
.analysis-chart-card-content {
height: 40px;
}
.analysis-trend-text {
white-space: nowrap;
}
</style>

View File

@@ -0,0 +1,101 @@
<template>
<a-card
:bordered="false"
title="最近1小时访问情况"
:body-style="{ padding: '16px 6px 0 0' }"
>
<v-chart
ref="visitHourChartRef"
:option="visitHourChartOption"
style="height: 362px"
/>
</a-card>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { message } from 'ant-design-vue/es';
import { use } from 'echarts/core';
import type { EChartsCoreOption } from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import { LineChart } from 'echarts/charts';
import {
GridComponent,
TooltipComponent,
LegendComponent
} from 'echarts/components';
import VChart from 'vue-echarts';
import { getVisitHourList } from '@/api/dashboard/analysis';
import useEcharts from '@/utils/use-echarts';
use([
CanvasRenderer,
LineChart,
GridComponent,
TooltipComponent,
LegendComponent
]);
//
const visitHourChartRef = ref<InstanceType<typeof VChart> | null>(null);
useEcharts([visitHourChartRef]);
// 最近 1 小时访问情况折线图配置
const visitHourChartOption: EChartsCoreOption = reactive({});
/* 获取最近 1 小时访问情况数据 */
const getVisitHourData = () => {
getVisitHourList()
.then((data) => {
Object.assign(visitHourChartOption, {
tooltip: {
trigger: 'axis'
},
legend: {
data: ['浏览量', '访问量'],
right: 20
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: data.map((d) => d.time)
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '浏览量',
type: 'line',
smooth: true,
symbol: 'none',
areaStyle: {
opacity: 0.5
},
data: data.map((d) => d.views)
},
{
name: '访问量',
type: 'line',
smooth: true,
symbol: 'none',
areaStyle: {
opacity: 0.5
},
data: data.map((d) => d.visits)
}
]
});
})
.catch((e) => {
message.error(e.message);
});
};
getVisitHourData();
</script>

View File

@@ -0,0 +1,39 @@
<template>
<div class="ele-body ele-body-card">
<statistics-card :data="statistics" />
<sale-card />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { storeToRefs } from 'pinia';
import { useThemeStore } from '@/store/modules/theme';
//import * as ShopCountApi from '@/api/shop/count';
import StatisticsCard from './components/statistics-card.vue';
import SaleCard from './components/sale-card.vue';
import VisitHour from './components/visit-hour.vue';
import HotSearch from './components/hot-search.vue';
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const statistics = ref();
const reload = () => {
// ShopCountApi.data({}).then((list) => {
// if (list) {
// statistics.value = list;
// }
// });
};
reload();
</script>
<script lang="ts">
export default {
name: 'DashboardAnalysis'
};
</script>

View File

@@ -304,7 +304,18 @@
<template v-if="column.key === 'expirationDay'">
<span class="ele-text-danger">{{ expirationDay(record) }}</span>
</template>
<template v-if="column.key === 'action'">
<view >
<a-button
class="ele-text-danger"
@click="openOrderOnline(record)"
>退租</a-button>
</view>
</template>
</template>
</a-table>
</a-spin>
</a-card>
@@ -403,6 +414,11 @@
</a-col>
</a-row>
</a-card>
<order-online
v-model:visible="showOrderOnline"
/>
</ele-modal>
</template>
@@ -415,6 +431,7 @@ import {formatNumber} from 'ele-admin-pro/es';
import {storeToRefs} from 'pinia';
import {copyText} from '@/utils/common';
import {Order} from '@/api/order/model';
import OrderOnline from '../components/order-online.vue';
import {listEquipmentOrderGoods} from '@/api/apps/equipment/order/goods';
import {EquipmentOrderGoods} from '@/api/apps/equipment/order/goods/model';
import * as EquipmentApi from '@/api/apps/equipment';
@@ -423,12 +440,17 @@ import {ColumnItem, DatasourceFunction} from 'ele-admin-pro/es/ele-pro-table/typ
import {listOrder, listOrderPay} from '@/api/order';
import {CopyOutlined} from '@ant-design/icons-vue';
import {EquipmentRecord} from '@/api/apps/equipment/record/model';
import OrderRefund from "@/views/yunxinwei/order/components/order-refund.vue";
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const {styleResponsive} = storeToRefs(themeStore);
const showOrderOnline = ref(false);
// 当前编辑数据
const current = ref<Order | null>(null);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
@@ -600,7 +622,15 @@ const columns2 = ref<ColumnItem[]>([
title: '逾期状态',
dataIndex: 'expirationDay',
key: 'expirationDay'
}
},
{
title: '操作',
key: 'action',
width: 100,
align: 'center',
fixed: 'left',
hideInSetting: true
},
]);
const columns3 = ref<ColumnItem[]>([
{
@@ -702,6 +732,13 @@ const getEquipmentOrderGoods = () => {
});
};
/* 线下缴费 */
const openOrderOnline = (row?: Order) => {
current.value = row ?? null;
showOrderOnline.value = true;
};
const getEquipment = () => {
EquipmentApi.listEquipment({orderId: order.orderId}).then((data) => {
if (data.length > 0) {

View File

@@ -0,0 +1,186 @@
<!-- 用户编辑弹窗 -->
<template>
<ele-modal
:width="500"
:visible="visible"
:confirm-loading="loading"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '发货' : '发货'"
:body-style="{ paddingBottom: '8px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-space>
<a-form>
<a-form-item label="设备编码" v-bind="validateInfos.equipmentCode">
<a-input
allow-clear
:maxlength="30"
placeholder="请输入设备编码"
v-model:value="form.equipmentCode"
@blur="
validate('equipmentCode', { trigger: 'blur' }).catch(() => {})
"
/>
</a-form-item>
<!-- <a-row :gutter="16">-->
<!-- <a-col :md="12" :sm="24" :xs="24">-->
<!-- <a-form-item label="选择设备" v-bind="validateInfos.customerName">-->
<!-- <a-input-->
<!-- allow-clear-->
<!-- :maxlength="30"-->
<!-- placeholder="请选择设备"-->
<!-- v-model:value="form.customerName"-->
<!-- @blur="-->
<!-- validate('customerName', { trigger: 'blur' }).catch(() => {})-->
<!-- "-->
<!-- />-->
<!-- </a-form-item>-->
<!-- </a-col>-->
<!-- <a-col :md="12" :sm="24" :xs="24">-->
<!-- <a-form-item label="手机号码" v-bind="validateInfos.customerMobile">-->
<!-- <a-input-->
<!-- allow-clear-->
<!-- :maxlength="20"-->
<!-- placeholder="请填写联系人手机号码"-->
<!-- v-model:value="form.customerMobile"-->
<!-- />-->
<!-- </a-form-item>-->
<!-- </a-col>-->
<!-- </a-row>-->
</a-form>
</a-space>
</ele-modal>
</template>
<script lang="ts" setup>
import {ref, reactive, watch, computed} from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject } from 'ele-admin-pro';
import TypeSelect from './customer-edit/type-select.vue';
import ProgressSelect from './customer-edit/progress-select.vue';
import SourceSelect from './customer-edit/source-select.vue';
import { bindEquipment } from '@/api/apps/equipment';
import type { Customer } from '@/api/oa/customer/model';
import { createCode } from '@/utils/common';
import { uploadFile } from '@/api/system/file';
import type { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FILE_SERVER } from '@/config/setting';
import { useUserStore } from '@/store/modules/user';
import { Equipment } from "@/api/apps/equipment/model";
import { Order } from "@/api/order/model";
const userStore = useUserStore();
// 当前用户信息
const loginUser = computed(() => userStore.info ?? {});
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: Order | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表单数据
const form = reactive<Equipment>({
equipmentCode: '',
orderId: undefined
});
// 已上传数据, 可赋初始值用于回显
const images = ref(<any>[]);
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
equipmentCode: [
{
required: true,
type: 'string',
message: '请输入设备编码',
trigger: 'blur'
}
]
});
const { resetFields, validate, validateInfos } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
validate()
.then(() => {
loading.value = true;
// 去除空格
const data = {
...form,
orderId: props.data?.orderId,
userId: props.data?.userId
};
// 转字符串
bindEquipment(data)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
const onUpload = (d: ItemType) => {
uploadFile(<File>d.file)
.then((result) => {
form.customerAvatar = result.path;
message.success('上传成功');
})
.catch((e) => {
message.error(e.message);
});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
if (props.data) {
loading.value = false;
// 头像赋值
images.value = [];
if(props.data.customerAvatar){
images.value.push({ uid:1, url: FILE_SERVER + props.data.customerAvatar, status: '' });
}
assignObject(form, props.data);
isUpdate.value = true;
} else {
form.customerCode = createCode();
isUpdate.value = false;
}
} else {
resetFields();
}
}
);
</script>
<style lang="less"></style>