|
|
@@ -1,8 +1,8 @@
|
|
|
<script setup lang="ts">
|
|
|
import { useTableComponents } from '@/components/ZmTable/useTableComponents'
|
|
|
-import { IotSapStockApi, IotSapStockVO } from '@/api/pms/iotsapstock'
|
|
|
+import { IotSapStockApi, IotSapStockVO, SapStockSummaryVO } from '@/api/pms/iotsapstock'
|
|
|
import * as SapOrgApi from '@/api/system/saporg'
|
|
|
-import { dateFormatter } from '@/utils/formatTime'
|
|
|
+import { dateFormatter, rangeShortcuts } from '@/utils/formatTime'
|
|
|
import download from '@/utils/download'
|
|
|
import CountTo from '@/components/count-to1.vue'
|
|
|
|
|
|
@@ -83,10 +83,10 @@ const queryParams = reactive<QueryParams>({ ...initQuery })
|
|
|
const queryFormRef = ref()
|
|
|
const loading = ref(false)
|
|
|
const exportLoading = ref(false)
|
|
|
+const summaryLoading = ref(false)
|
|
|
const list = ref<StockRow[]>([])
|
|
|
const total = ref(0)
|
|
|
-const totalQuantity = ref(0)
|
|
|
-const totalAmount = ref(0)
|
|
|
+const stockSummary = ref<SapStockSummaryVO[]>([])
|
|
|
const factoryList = ref<SapOrgApi.SapOrgVO[]>([])
|
|
|
const storageLocationList = ref<SapOrgApi.SapOrgVO[]>([])
|
|
|
|
|
|
@@ -96,24 +96,31 @@ const resultOptions = computed(() => [
|
|
|
{ label: '否', value: 'N' }
|
|
|
])
|
|
|
|
|
|
-const stockStatCards = computed(() => [
|
|
|
- {
|
|
|
- label: t('stock.totalQuantity'),
|
|
|
- value: totalQuantity.value,
|
|
|
- prefix: '',
|
|
|
- unit: '',
|
|
|
- decimals: 0,
|
|
|
- icon: 'i-tabler:packages text-sky'
|
|
|
- },
|
|
|
- {
|
|
|
- label: t('stock.totalAmount'),
|
|
|
- value: totalAmount.value,
|
|
|
- prefix: '¥',
|
|
|
- unit: '',
|
|
|
- decimals: 2,
|
|
|
- icon: 'i-material-symbols:payments-outline-rounded text-emerald'
|
|
|
+const totalQuantity = computed(() =>
|
|
|
+ stockSummary.value.reduce((totalValue, item) => totalValue + Number(item.totalQuantity || 0), 0)
|
|
|
+)
|
|
|
+
|
|
|
+const getCurrencySymbol = (currency: string) => {
|
|
|
+ const currencySymbols: Record<string, string> = {
|
|
|
+ CNY: '¥',
|
|
|
+ USD: '$'
|
|
|
}
|
|
|
-])
|
|
|
+ const currencyCode = currency.trim().toUpperCase()
|
|
|
+ return currencySymbols[currencyCode] || currencyCode
|
|
|
+}
|
|
|
+
|
|
|
+const getCurrencyName = (currency: string) => {
|
|
|
+ const currencyNames: Record<string, string> = {
|
|
|
+ CNY: '人民币',
|
|
|
+ USD: '美元'
|
|
|
+ }
|
|
|
+ return currencyNames[currency.trim().toUpperCase()] || '其他币种'
|
|
|
+}
|
|
|
+
|
|
|
+const getCurrencyClass = (currency: string) => {
|
|
|
+ const currencyCode = currency.trim().toLowerCase()
|
|
|
+ return ['cny', 'usd'].includes(currencyCode) ? `currency-card--${currencyCode}` : ''
|
|
|
+}
|
|
|
|
|
|
const getList = async () => {
|
|
|
loading.value = true
|
|
|
@@ -121,15 +128,20 @@ const getList = async () => {
|
|
|
const data = await IotSapStockApi.getIotSapStockPage(queryParams)
|
|
|
list.value = data.list
|
|
|
total.value = data.total
|
|
|
-
|
|
|
- const firstRow = data.list?.[0]
|
|
|
- totalQuantity.value = Number(firstRow?.totalQuantity) || 0
|
|
|
- totalAmount.value = Number(firstRow?.totalAmount) || 0
|
|
|
} finally {
|
|
|
loading.value = false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const getSapStockSummary = async () => {
|
|
|
+ summaryLoading.value = true
|
|
|
+ try {
|
|
|
+ stockSummary.value = await IotSapStockApi.getSapStockSummary(queryParams)
|
|
|
+ } finally {
|
|
|
+ summaryLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const loadSapOrgOptions = async () => {
|
|
|
const [factories, storageLocations] = await Promise.all([
|
|
|
SapOrgApi.SapOrgApi.getSimpleSapOrgList(1),
|
|
|
@@ -142,6 +154,7 @@ const loadSapOrgOptions = async () => {
|
|
|
const handleQuery = () => {
|
|
|
queryParams.pageNo = 1
|
|
|
getList()
|
|
|
+ getSapStockSummary()
|
|
|
}
|
|
|
|
|
|
const resetQuery = () => {
|
|
|
@@ -152,7 +165,8 @@ const resetQuery = () => {
|
|
|
|
|
|
const handleSizeChange = (val: number) => {
|
|
|
queryParams.pageSize = val
|
|
|
- handleQuery()
|
|
|
+ queryParams.pageNo = 1
|
|
|
+ getList()
|
|
|
}
|
|
|
|
|
|
const handleCurrentChange = (val: number) => {
|
|
|
@@ -191,20 +205,19 @@ const handleExport = async () => {
|
|
|
onMounted(() => {
|
|
|
loadSapOrgOptions()
|
|
|
getList()
|
|
|
+ getSapStockSummary()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div
|
|
|
- class="iot-sap-stock-page grid grid-rows-[auto_auto_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]"
|
|
|
- >
|
|
|
+ class="iot-sap-stock-page grid grid-rows-[auto_auto_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]">
|
|
|
<el-form
|
|
|
ref="queryFormRef"
|
|
|
:model="queryParams"
|
|
|
size="default"
|
|
|
label-width="82px"
|
|
|
- class="iot-sap-stock-query bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-6 py-3 min-w-0"
|
|
|
- >
|
|
|
+ class="iot-sap-stock-query bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-6 py-3 min-w-0">
|
|
|
<div class="query-row">
|
|
|
<el-form-item :label="t('workOrderMaterial.factory')" prop="factoryId">
|
|
|
<el-select
|
|
|
@@ -213,14 +226,12 @@ onMounted(() => {
|
|
|
filterable
|
|
|
:placeholder="t('faultForm.choose')"
|
|
|
class="query-control"
|
|
|
- @change="selectedFactoryChange"
|
|
|
- >
|
|
|
+ @change="selectedFactoryChange">
|
|
|
<el-option
|
|
|
v-for="item in factoryList"
|
|
|
:key="item.id"
|
|
|
:label="item.factoryName"
|
|
|
- :value="item.id!"
|
|
|
- />
|
|
|
+ :value="item.id!" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item :label="t('workOrderMaterial.storageLocation')" prop="storageLocationId">
|
|
|
@@ -229,14 +240,12 @@ onMounted(() => {
|
|
|
clearable
|
|
|
filterable
|
|
|
:placeholder="t('faultForm.choose')"
|
|
|
- class="query-control"
|
|
|
- >
|
|
|
+ class="query-control">
|
|
|
<el-option
|
|
|
v-for="item in storageLocationList"
|
|
|
:key="item.id"
|
|
|
:label="item.storageLocationName"
|
|
|
- :value="item.id!"
|
|
|
- />
|
|
|
+ :value="item.id!" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item :label="t('chooseMaintain.materialCode')" prop="materialCode">
|
|
|
@@ -245,8 +254,7 @@ onMounted(() => {
|
|
|
:placeholder="t('chooseMaintain.materialCode')"
|
|
|
clearable
|
|
|
class="query-control"
|
|
|
- @keyup.enter="handleQuery"
|
|
|
- />
|
|
|
+ @keyup.enter="handleQuery" />
|
|
|
</el-form-item>
|
|
|
<el-form-item :label="t('chooseMaintain.materialName')" prop="materialName">
|
|
|
<el-input
|
|
|
@@ -254,33 +262,30 @@ onMounted(() => {
|
|
|
:placeholder="t('chooseMaintain.materialName')"
|
|
|
clearable
|
|
|
class="query-control"
|
|
|
- @keyup.enter="handleQuery"
|
|
|
- />
|
|
|
+ @keyup.enter="handleQuery" />
|
|
|
</el-form-item>
|
|
|
<el-form-item :label="t('chooseMaintain.createTime')" prop="createTime">
|
|
|
<el-date-picker
|
|
|
v-model="queryParams.createTime"
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
type="daterange"
|
|
|
+ :shortcuts="rangeShortcuts"
|
|
|
:start-placeholder="t('info.start')"
|
|
|
:end-placeholder="t('info.end')"
|
|
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
|
|
- class="query-control query-control--date"
|
|
|
- />
|
|
|
+ class="query-control query-control--date" />
|
|
|
</el-form-item>
|
|
|
<el-form-item :label="t('route.IsItConfigured')" prop="configFlag" label-width="116px">
|
|
|
<el-select
|
|
|
v-model="queryParams.configFlag"
|
|
|
:placeholder="t('faultForm.choose')"
|
|
|
clearable
|
|
|
- class="query-control query-control--small"
|
|
|
- >
|
|
|
+ class="query-control query-control--small">
|
|
|
<el-option
|
|
|
v-for="dict in resultOptions"
|
|
|
:key="dict.value"
|
|
|
:label="dict.label"
|
|
|
- :value="dict.value"
|
|
|
- />
|
|
|
+ :value="dict.value" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
</div>
|
|
|
@@ -300,26 +305,55 @@ onMounted(() => {
|
|
|
</div>
|
|
|
</el-form>
|
|
|
|
|
|
- <div class="stock-stat-grid">
|
|
|
- <div v-for="item in stockStatCards" :key="item.label" class="stock-stat-card group">
|
|
|
- <div class="relative z-10 flex h-full flex-col justify-center">
|
|
|
- <span class="stat-label">{{ item.label }}</span>
|
|
|
- <div class="flex items-baseline gap-1">
|
|
|
- <span v-if="item.prefix" class="text-[12px] text-gray-400">{{ item.prefix }}</span>
|
|
|
- <count-to
|
|
|
- class="stat-value"
|
|
|
- :start-val="0"
|
|
|
- :end-val="item.value"
|
|
|
- :decimals="item.decimals"
|
|
|
- />
|
|
|
- <span v-if="item.unit" class="stat-unit">{{ item.unit }}</span>
|
|
|
+ <section class="stock-overview" v-loading="summaryLoading">
|
|
|
+ <div class="quantity-overview">
|
|
|
+ <div class="quantity-icon">
|
|
|
+ <Icon icon="ep:box" class="quantity-icon__glyph" />
|
|
|
+ </div>
|
|
|
+ <div class="quantity-content">
|
|
|
+ <div class="quantity-label">{{ t('stock.totalQuantity') }}</div>
|
|
|
+ <count-to class="quantity-value" :start-val="0" :end-val="totalQuantity" :decimals="2" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="currency-overview">
|
|
|
+ <div class="currency-overview__header">
|
|
|
+ <div class="currency-overview__title">
|
|
|
+ <Icon icon="ep:wallet" />
|
|
|
+ <span>库存总金额</span>
|
|
|
</div>
|
|
|
+ <div class="currency-overview__subtitle">按币种独立核算</div>
|
|
|
</div>
|
|
|
- <div class="stat-icon">
|
|
|
- <div :class="item.icon" class="text-5xl"></div>
|
|
|
+
|
|
|
+ <div v-if="stockSummary.length" class="currency-grid">
|
|
|
+ <div
|
|
|
+ v-for="item in stockSummary"
|
|
|
+ :key="item.currency"
|
|
|
+ class="currency-card"
|
|
|
+ :class="getCurrencyClass(item.currency)">
|
|
|
+ <div class="currency-token">{{ getCurrencySymbol(item.currency) }}</div>
|
|
|
+ <div class="currency-card__content">
|
|
|
+ <div class="currency-card__heading">
|
|
|
+ <span class="currency-name">{{ getCurrencyName(item.currency) }}</span>
|
|
|
+ <span class="currency-code">{{ item.currency }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="currency-card__amount">
|
|
|
+ <span class="currency-symbol">{{ getCurrencySymbol(item.currency) }}</span>
|
|
|
+ <count-to
|
|
|
+ class="currency-value"
|
|
|
+ :start-val="0"
|
|
|
+ :end-val="Number(item.totalAmount) || 0"
|
|
|
+ :decimals="2" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-else-if="!summaryLoading" class="summary-empty">
|
|
|
+ <Icon icon="ep:coin" />
|
|
|
+ <span>暂无金额汇总数据</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
+ </section>
|
|
|
|
|
|
<div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg flex flex-col p-4 min-w-0 min-h-0">
|
|
|
<div class="flex-1 relative min-h-0">
|
|
|
@@ -331,50 +365,25 @@ onMounted(() => {
|
|
|
:width="width"
|
|
|
:height="height"
|
|
|
:max-height="height"
|
|
|
- show-border
|
|
|
- >
|
|
|
+ show-border>
|
|
|
<ZmTableColumn
|
|
|
type="index"
|
|
|
:label="t('monitor.serial')"
|
|
|
:width="70"
|
|
|
fixed="left"
|
|
|
- hide-in-column-settings
|
|
|
- />
|
|
|
- <ZmTableColumn
|
|
|
- prop="factory"
|
|
|
- :label="t('workOrderMaterial.factory')"
|
|
|
- min-width="120"
|
|
|
- />
|
|
|
+ hide-in-column-settings />
|
|
|
+ <ZmTableColumn prop="factory" :label="t('workOrderMaterial.factory')" />
|
|
|
<ZmTableColumn
|
|
|
prop="projectDepartment"
|
|
|
- :label="t('workOrderMaterial.storageLocation')"
|
|
|
- min-width="140"
|
|
|
- />
|
|
|
- <ZmTableColumn
|
|
|
- prop="materialCode"
|
|
|
- :label="t('chooseMaintain.materialCode')"
|
|
|
- min-width="150"
|
|
|
- />
|
|
|
- <ZmTableColumn
|
|
|
- prop="materialName"
|
|
|
- :label="t('chooseMaintain.materialName')"
|
|
|
- min-width="220"
|
|
|
- align="left"
|
|
|
- />
|
|
|
- <ZmTableColumn prop="quantity" :label="t('route.quantity')" min-width="100" />
|
|
|
- <ZmTableColumn
|
|
|
- prop="unitPrice"
|
|
|
- :label="t('workOrderMaterial.unitPrice')"
|
|
|
- min-width="100"
|
|
|
- />
|
|
|
- <ZmTableColumn prop="unit" :label="t('workOrderMaterial.unit')" min-width="90" />
|
|
|
- <ZmTableColumn prop="safetyStock" :label="t('route.safetyStock')" min-width="120" />
|
|
|
- <ZmTableColumn
|
|
|
- prop="createTime"
|
|
|
- :label="t('chooseMaintain.createTime')"
|
|
|
- min-width="180"
|
|
|
- action
|
|
|
- >
|
|
|
+ :label="t('workOrderMaterial.storageLocation')" />
|
|
|
+ <ZmTableColumn prop="materialCode" :label="t('chooseMaintain.materialCode')" />
|
|
|
+ <ZmTableColumn prop="materialName" :label="t('chooseMaintain.materialName')" />
|
|
|
+ <ZmTableColumn prop="quantity" :label="t('route.quantity')" />
|
|
|
+ <ZmTableColumn prop="unitPrice" :label="t('workOrderMaterial.unitPrice')" />
|
|
|
+ <ZmTableColumn prop="currency" label="币种" />
|
|
|
+ <ZmTableColumn prop="unit" :label="t('workOrderMaterial.unit')" />
|
|
|
+ <ZmTableColumn prop="safetyStock" :label="t('route.safetyStock')" />
|
|
|
+ <ZmTableColumn prop="createTime" :label="t('chooseMaintain.createTime')" action>
|
|
|
<template #default="{ row }">
|
|
|
{{ dateFormatter(row, null, row.createTime) }}
|
|
|
</template>
|
|
|
@@ -395,8 +404,7 @@ onMounted(() => {
|
|
|
:total="total"
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
@size-change="handleSizeChange"
|
|
|
- @current-change="handleCurrentChange"
|
|
|
- />
|
|
|
+ @current-change="handleCurrentChange" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -429,67 +437,233 @@ onMounted(() => {
|
|
|
gap: 12px 18px;
|
|
|
}
|
|
|
|
|
|
-.stat-label {
|
|
|
- margin-bottom: 2px;
|
|
|
+.stock-overview {
|
|
|
+ position: relative;
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: minmax(280px, 0.72fr) minmax(0, 1.48fr);
|
|
|
+ min-height: 88px;
|
|
|
+ overflow: hidden;
|
|
|
+ background: var(--el-bg-color);
|
|
|
+ border: 1px solid var(--el-border-color-lighter);
|
|
|
+ border-radius: 12px;
|
|
|
+ box-shadow: 0 3px 12px rgb(31 45 61 / 7%);
|
|
|
+}
|
|
|
+
|
|
|
+.stock-overview::before {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ left: 0;
|
|
|
+ z-index: 2;
|
|
|
+ height: 2px;
|
|
|
+ background: linear-gradient(90deg, var(--el-color-primary), var(--el-color-success));
|
|
|
+ content: '';
|
|
|
+}
|
|
|
+
|
|
|
+.quantity-overview {
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ min-width: 0;
|
|
|
+ padding: 12px 22px;
|
|
|
+ background: linear-gradient(90deg, var(--el-color-primary-light-9), transparent 70%);
|
|
|
+ border-right: 1px solid var(--el-border-color-lighter);
|
|
|
+}
|
|
|
+
|
|
|
+.quantity-icon {
|
|
|
+ display: flex;
|
|
|
+ flex: 0 0 auto;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ margin-right: 13px;
|
|
|
+ color: #fff;
|
|
|
+ background: linear-gradient(145deg, var(--el-color-primary-light-3), var(--el-color-primary));
|
|
|
+ border-radius: 11px;
|
|
|
+ box-shadow: 0 5px 12px var(--el-color-primary-light-7);
|
|
|
+}
|
|
|
+
|
|
|
+.quantity-icon__glyph {
|
|
|
+ font-size: 21px;
|
|
|
+}
|
|
|
+
|
|
|
+.quantity-content {
|
|
|
+ min-width: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.quantity-label {
|
|
|
font-size: 11px;
|
|
|
- font-weight: 500;
|
|
|
- letter-spacing: 0;
|
|
|
- color: var(--el-text-color-regular);
|
|
|
+ color: var(--el-text-color-secondary);
|
|
|
}
|
|
|
|
|
|
-.stat-value {
|
|
|
+.quantity-value {
|
|
|
+ display: block;
|
|
|
+ margin-top: 5px;
|
|
|
font-family: var(--el-font-family);
|
|
|
- font-size: 18px;
|
|
|
- font-weight: 700;
|
|
|
+ font-size: 23px;
|
|
|
+ font-weight: 750;
|
|
|
line-height: 1;
|
|
|
+ letter-spacing: -0.5px;
|
|
|
color: var(--el-text-color-primary);
|
|
|
}
|
|
|
|
|
|
-.stat-unit {
|
|
|
+.currency-overview {
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ min-width: 0;
|
|
|
+ padding: 10px 18px;
|
|
|
+}
|
|
|
+
|
|
|
+.currency-overview__header {
|
|
|
+ flex: 0 0 108px;
|
|
|
+}
|
|
|
+
|
|
|
+.currency-overview__title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 650;
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
+}
|
|
|
+
|
|
|
+.currency-overview__title .el-icon,
|
|
|
+.currency-overview__title > :first-child {
|
|
|
+ margin-right: 6px;
|
|
|
+ color: var(--el-color-success);
|
|
|
+}
|
|
|
+
|
|
|
+.currency-overview__subtitle {
|
|
|
+ margin-top: 5px;
|
|
|
font-size: 10px;
|
|
|
- font-weight: 400;
|
|
|
- color: var(--el-text-color-secondary);
|
|
|
+ color: var(--el-text-color-placeholder);
|
|
|
}
|
|
|
|
|
|
-.stock-stat-grid {
|
|
|
- display: grid;
|
|
|
- grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
- gap: 12px;
|
|
|
+.currency-grid {
|
|
|
+ flex: 1 1 auto;
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ min-width: 0;
|
|
|
+ margin-left: 16px;
|
|
|
+ overflow: auto hidden;
|
|
|
}
|
|
|
|
|
|
-.stock-stat-card {
|
|
|
- position: relative;
|
|
|
- min-height: 78px;
|
|
|
- padding: 10px 14px;
|
|
|
- overflow: hidden;
|
|
|
- background-color: var(--el-bg-color);
|
|
|
+.currency-card {
|
|
|
+ --currency-color: var(--el-color-warning);
|
|
|
+ --currency-soft: var(--el-color-warning-light-9);
|
|
|
+
|
|
|
+ display: flex;
|
|
|
+ flex: 1 0 210px;
|
|
|
+ align-items: center;
|
|
|
+ min-width: 0;
|
|
|
+ padding: 7px 10px;
|
|
|
+ background: linear-gradient(120deg, var(--currency-soft), var(--el-bg-color) 72%);
|
|
|
border: 1px solid var(--el-border-color-extra-light);
|
|
|
border-radius: 8px;
|
|
|
- box-shadow: var(--el-box-shadow-lighter);
|
|
|
transition:
|
|
|
- border-color 0.3s,
|
|
|
- box-shadow 0.3s;
|
|
|
+ border-color 0.25s ease,
|
|
|
+ box-shadow 0.25s ease,
|
|
|
+ transform 0.25s ease;
|
|
|
}
|
|
|
|
|
|
-.stock-stat-card:hover {
|
|
|
- border-color: var(--el-color-primary-light-7);
|
|
|
- box-shadow: var(--el-box-shadow-light);
|
|
|
+.currency-card:hover {
|
|
|
+ border-color: var(--currency-color);
|
|
|
+ box-shadow: 0 4px 10px rgb(31 45 61 / 7%);
|
|
|
}
|
|
|
|
|
|
-.stat-icon {
|
|
|
- position: absolute;
|
|
|
- right: -8px;
|
|
|
- bottom: -12px;
|
|
|
- opacity: 0.4;
|
|
|
- transform: rotate(-10deg);
|
|
|
- transition:
|
|
|
- transform 0.5s,
|
|
|
- opacity 0.5s;
|
|
|
+.currency-card--cny {
|
|
|
+ --currency-color: var(--el-color-danger);
|
|
|
+ --currency-soft: var(--el-color-danger-light-9);
|
|
|
+}
|
|
|
+
|
|
|
+.currency-card--usd {
|
|
|
+ --currency-color: var(--el-color-primary);
|
|
|
+ --currency-soft: var(--el-color-primary-light-9);
|
|
|
+}
|
|
|
+
|
|
|
+.currency-token {
|
|
|
+ display: flex;
|
|
|
+ flex: 0 0 auto;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ margin-right: 9px;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 750;
|
|
|
+ color: var(--currency-color);
|
|
|
+ background: var(--el-bg-color);
|
|
|
+ border: 1px solid var(--currency-color);
|
|
|
+ border-radius: 9px;
|
|
|
+}
|
|
|
+
|
|
|
+.currency-card__content {
|
|
|
+ min-width: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.currency-card__heading {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.currency-name {
|
|
|
+ font-size: 11px;
|
|
|
+ color: var(--el-text-color-secondary);
|
|
|
+}
|
|
|
+
|
|
|
+.currency-code {
|
|
|
+ padding: 2px 5px;
|
|
|
+ margin-left: 6px;
|
|
|
+ font-size: 9px;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 1;
|
|
|
+ color: var(--currency-color);
|
|
|
+ background: var(--el-bg-color);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.currency-card__amount {
|
|
|
+ display: flex;
|
|
|
+ align-items: baseline;
|
|
|
+ min-width: 0;
|
|
|
+ margin-top: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.currency-symbol {
|
|
|
+ margin-right: 4px;
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: var(--currency-color);
|
|
|
+}
|
|
|
+
|
|
|
+.currency-value {
|
|
|
+ font-family: var(--el-font-family);
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 750;
|
|
|
+ line-height: 1;
|
|
|
+ letter-spacing: -0.2px;
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
+}
|
|
|
+
|
|
|
+.summary-empty {
|
|
|
+ flex: 1 1 auto;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ min-height: 44px;
|
|
|
+ margin-left: 16px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--el-text-color-placeholder);
|
|
|
+ background: var(--el-fill-color-extra-light);
|
|
|
+ border: 1px dashed var(--el-border-color);
|
|
|
+ border-radius: 8px;
|
|
|
}
|
|
|
|
|
|
-.stock-stat-card:hover .stat-icon {
|
|
|
- opacity: 0.55;
|
|
|
- transform: scale(1.08) rotate(0);
|
|
|
+.summary-empty > :first-child {
|
|
|
+ margin-right: 6px;
|
|
|
}
|
|
|
|
|
|
.query-actions {
|
|
|
@@ -564,6 +738,17 @@ onMounted(() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+@media (width <= 900px) {
|
|
|
+ .stock-overview {
|
|
|
+ grid-template-columns: minmax(0, 1fr);
|
|
|
+ }
|
|
|
+
|
|
|
+ .quantity-overview {
|
|
|
+ border-right: 0;
|
|
|
+ border-bottom: 1px solid var(--el-border-color-lighter);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
@media (width <= 768px) {
|
|
|
.iot-sap-stock-query {
|
|
|
padding: 12px;
|
|
|
@@ -582,8 +767,18 @@ onMounted(() => {
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
- .stock-stat-grid {
|
|
|
- grid-template-columns: minmax(0, 1fr);
|
|
|
+ .quantity-overview,
|
|
|
+ .currency-overview {
|
|
|
+ padding: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .currency-overview {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+
|
|
|
+ .currency-grid {
|
|
|
+ margin-top: 10px;
|
|
|
+ margin-left: 0;
|
|
|
}
|
|
|
|
|
|
.query-actions :deep(.el-form-item__content) {
|