feat: 完成后台联调与通用列表组件
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Eye, FilePenLine, PackageCheck, RotateCcw, Search } from '@lucide/vue'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { Eye, FilePenLine, PackageCheck } from '@lucide/vue'
|
||||
import {
|
||||
acceptPlatformFirstLegOrder,
|
||||
addPlatformFirstLegOrderNote,
|
||||
@@ -18,18 +19,18 @@ import {
|
||||
} from '@/api/platformFirstLegOrders'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/api/http'
|
||||
import ApiErrorMeta from '@/components/ApiErrorMeta.vue'
|
||||
import MetricStrip from '@/components/MetricStrip.vue'
|
||||
import StatusBadge from '@/components/StatusBadge.vue'
|
||||
import DataTable, { type DataTableColumn } from '@/components/common/DataTable.vue'
|
||||
import QueryToolbar, { type QueryField, type QueryModel } from '@/components/common/QueryToolbar.vue'
|
||||
import { useAccessPreviewStore } from '@/stores/accessPreview'
|
||||
|
||||
const TENANT_SESSION_KEY = 'cc-admin-first-leg-order-tenant-id'
|
||||
const PHASE_ONE_TENANT_ID = '10001'
|
||||
const access = useAccessPreviewStore()
|
||||
const tenantId = ref(sessionStorage.getItem(TENANT_SESSION_KEY) || '')
|
||||
const loadedTenantId = ref('')
|
||||
const loadedTenantId = ref(PHASE_ONE_TENANT_ID)
|
||||
const orders = ref<PlatformFirstLegOrderResource[]>([])
|
||||
const total = ref(0)
|
||||
const page = ref(1)
|
||||
const pageSize = 20
|
||||
const pageSize = ref(20)
|
||||
const loading = ref(false)
|
||||
const actionLoadingId = ref('')
|
||||
const loadError = ref<ApiErrorDetails | null>(null)
|
||||
@@ -39,23 +40,64 @@ const detail = ref<PlatformFirstLegOrderDetailResource | null>(null)
|
||||
const noteDialogOpen = ref(false)
|
||||
const expressDialogOpen = ref(false)
|
||||
const selectedOrder = ref<PlatformFirstLegOrderResource | null>(null)
|
||||
const noteContent = ref('')
|
||||
const noteForm = reactive({ content: '' })
|
||||
const noteSaving = ref(false)
|
||||
const expressSaving = ref(false)
|
||||
const expressFormRef = ref<FormInstance>()
|
||||
const noteFormRef = ref<FormInstance>()
|
||||
const expressForm = reactive({ expressCompany: '', expressTrackingNo: '' })
|
||||
const filters = reactive<{ keyword: string; status: PlatformFirstLegOrderStatus | ''; dateRange: [string, string] | [] }>({
|
||||
const filters = ref<QueryModel & {
|
||||
keyword: string
|
||||
status: PlatformFirstLegOrderStatus | ''
|
||||
dateRange: string[]
|
||||
}>({
|
||||
keyword: '',
|
||||
status: '',
|
||||
dateRange: [],
|
||||
})
|
||||
|
||||
const tenantReady = computed(() => Boolean(loadedTenantId.value) && tenantId.value.trim() === loadedTenantId.value)
|
||||
const metrics = computed(() => [
|
||||
{ label: '订单总数', value: total.value, note: loadedTenantId.value ? `租户 ${loadedTenantId.value}` : '等待选择租户' },
|
||||
{ label: '待审核', value: orders.value.filter((item) => item.status === 'SUBMITTED').length, note: '当前页数据' },
|
||||
{ label: '履约处理中', value: orders.value.filter((item) => ['APPROVED', 'ACCEPTED', 'PROCESSING'].includes(item.status)).length, note: '当前页数据' },
|
||||
{ label: '已完成', value: orders.value.filter((item) => item.status === 'COMPLETED').length, note: '当前页数据' },
|
||||
])
|
||||
const queryFields: QueryField[] = [
|
||||
{ key: 'keyword', type: 'input', placeholder: '订单号或客户名称', props: { 'aria-label': '订单关键词' } },
|
||||
{
|
||||
key: 'status',
|
||||
type: 'select',
|
||||
placeholder: '全部状态',
|
||||
props: { 'aria-label': '订单状态' },
|
||||
options: [
|
||||
{ value: 'DRAFT', label: '草稿' },
|
||||
{ value: 'SUBMITTED', label: '待审核' },
|
||||
{ value: 'APPROVED', label: '已审核' },
|
||||
{ value: 'ACCEPTED', label: '已受理' },
|
||||
{ value: 'PROCESSING', label: '处理中' },
|
||||
{ value: 'COMPLETED', label: '已完成' },
|
||||
{ value: 'CANCELLED', label: '已取消' },
|
||||
{ value: 'REJECTED', label: '已驳回(旧契约)' },
|
||||
],
|
||||
},
|
||||
{ key: 'dateRange', type: 'daterange', props: { 'aria-label': '订单创建日期' } },
|
||||
]
|
||||
|
||||
const orderColumns: DataTableColumn[] = [
|
||||
{ key: 'actions', label: '操作', minWidth: 200, fixed: 'left', slotName: 'actions' },
|
||||
{ key: 'orderInfo', label: '订单信息', minWidth: 210, slotName: 'orderInfo' },
|
||||
{ key: 'customer', label: '客户', minWidth: 190, showOverflowTooltip: true, slotName: 'customer' },
|
||||
{ key: 'transport', label: '运输方案', minWidth: 180, slotName: 'transport' },
|
||||
{ key: 'destination', label: '目的地', minWidth: 150, slotName: 'destination' },
|
||||
{ key: 'receivingWarehouse', label: '平台收货仓', minWidth: 180, slotName: 'receivingWarehouse' },
|
||||
{ key: 'express', label: '履约快递', minWidth: 160, slotName: 'express' },
|
||||
{ key: 'status', label: '状态', width: 120, slotName: 'status' },
|
||||
]
|
||||
|
||||
const expressRules: FormRules = {
|
||||
expressCompany: [{ required: true, message: '请填写快递公司', trigger: 'blur' }],
|
||||
expressTrackingNo: [{ required: true, message: '请填写快递单号', trigger: 'blur' }],
|
||||
}
|
||||
|
||||
const noteRules: FormRules = {
|
||||
content: [{ required: true, message: '请填写内部备注', trigger: 'blur' }],
|
||||
}
|
||||
|
||||
const tenantReady = computed(() => loadedTenantId.value === PHASE_ONE_TENANT_ID)
|
||||
|
||||
const statusOptions: Array<{ value: PlatformFirstLegOrderStatus; label: string }> = [
|
||||
{ value: 'DRAFT', label: '草稿' },
|
||||
@@ -99,28 +141,22 @@ function actionLabel(order: PlatformFirstLegOrderResource) {
|
||||
return ''
|
||||
}
|
||||
|
||||
async function loadOrders(resetPage = false) {
|
||||
const targetTenantId = tenantId.value.trim()
|
||||
async function loadOrders() {
|
||||
const targetTenantId = PHASE_ONE_TENANT_ID
|
||||
loadError.value = null
|
||||
if (!/^\d+$/.test(targetTenantId) || targetTenantId === '0') {
|
||||
loadError.value = { message: '请输入有效的目标租户 ID 后查询订单' }
|
||||
return
|
||||
}
|
||||
if (resetPage) page.value = 1
|
||||
loading.value = true
|
||||
try {
|
||||
const result = await listPlatformFirstLegOrders(targetTenantId, {
|
||||
keyword: filters.keyword.trim() || undefined,
|
||||
status: filters.status || undefined,
|
||||
createdFrom: filters.dateRange.length === 2 ? `${filters.dateRange[0]}T00:00:00` : undefined,
|
||||
createdTo: filters.dateRange.length === 2 ? `${filters.dateRange[1]}T23:59:59` : undefined,
|
||||
keyword: filters.value.keyword.trim() || undefined,
|
||||
status: filters.value.status || undefined,
|
||||
createdFrom: filters.value.dateRange.length === 2 ? `${filters.value.dateRange[0]}T00:00:00` : undefined,
|
||||
createdTo: filters.value.dateRange.length === 2 ? `${filters.value.dateRange[1]}T23:59:59` : undefined,
|
||||
page: page.value,
|
||||
size: pageSize,
|
||||
size: pageSize.value,
|
||||
})
|
||||
orders.value = result.records
|
||||
total.value = result.total
|
||||
loadedTenantId.value = targetTenantId
|
||||
sessionStorage.setItem(TENANT_SESSION_KEY, targetTenantId)
|
||||
} catch (error) {
|
||||
orders.value = []
|
||||
total.value = 0
|
||||
@@ -130,18 +166,18 @@ async function loadOrders(resetPage = false) {
|
||||
}
|
||||
}
|
||||
|
||||
function resetFilters() {
|
||||
filters.keyword = ''
|
||||
filters.status = ''
|
||||
filters.dateRange = []
|
||||
void loadOrders(true)
|
||||
}
|
||||
|
||||
function handlePageChange(nextPage: number) {
|
||||
page.value = nextPage
|
||||
function searchOrders() {
|
||||
if (page.value !== 1) {
|
||||
page.value = 1
|
||||
return
|
||||
}
|
||||
void loadOrders()
|
||||
}
|
||||
|
||||
watch([page, pageSize], () => {
|
||||
void loadOrders()
|
||||
})
|
||||
|
||||
async function openDetail(order: PlatformFirstLegOrderResource) {
|
||||
if (!tenantReady.value) return
|
||||
selectedOrder.value = order
|
||||
@@ -217,14 +253,13 @@ function openExpress(order: PlatformFirstLegOrderResource) {
|
||||
expressForm.expressCompany = order.expressCompany || ''
|
||||
expressForm.expressTrackingNo = order.expressTrackingNo || ''
|
||||
expressDialogOpen.value = true
|
||||
void nextTick(() => expressFormRef.value?.clearValidate())
|
||||
}
|
||||
|
||||
async function saveExpress() {
|
||||
if (!selectedOrder.value || !tenantReady.value) return
|
||||
if (!expressForm.expressCompany.trim() || !expressForm.expressTrackingNo.trim()) {
|
||||
ElMessage.warning('请填写快递公司和快递单号')
|
||||
return
|
||||
}
|
||||
const valid = await expressFormRef.value?.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
expressSaving.value = true
|
||||
try {
|
||||
await updatePlatformFirstLegOrderExpress(loadedTenantId.value, String(selectedOrder.value.id), {
|
||||
@@ -243,19 +278,18 @@ async function saveExpress() {
|
||||
|
||||
function openNote(order: PlatformFirstLegOrderResource) {
|
||||
selectedOrder.value = order
|
||||
noteContent.value = ''
|
||||
noteForm.content = ''
|
||||
noteDialogOpen.value = true
|
||||
void nextTick(() => noteFormRef.value?.clearValidate())
|
||||
}
|
||||
|
||||
async function saveNote() {
|
||||
if (!selectedOrder.value || !tenantReady.value) return
|
||||
if (!noteContent.value.trim()) {
|
||||
ElMessage.warning('请填写内部备注')
|
||||
return
|
||||
}
|
||||
const valid = await noteFormRef.value?.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
noteSaving.value = true
|
||||
try {
|
||||
await addPlatformFirstLegOrderNote(loadedTenantId.value, String(selectedOrder.value.id), noteContent.value.trim())
|
||||
await addPlatformFirstLegOrderNote(loadedTenantId.value, String(selectedOrder.value.id), noteForm.content.trim())
|
||||
noteDialogOpen.value = false
|
||||
await refreshAfterAction(String(selectedOrder.value.id))
|
||||
ElMessage.success('内部备注已保存')
|
||||
@@ -267,55 +301,49 @@ async function saveNote() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (tenantId.value) void loadOrders()
|
||||
void loadOrders()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="business-page">
|
||||
<MetricStrip :items="metrics" />
|
||||
|
||||
<section class="surface-panel filter-panel" aria-label="头程订单筛选">
|
||||
<div class="filter-fields server-order-filter-fields">
|
||||
<el-input v-model.trim="tenantId" clearable placeholder="目标租户 ID" aria-label="目标租户 ID" @keyup.enter="loadOrders(true)" />
|
||||
<el-input v-model.trim="filters.keyword" clearable placeholder="订单号或客户名称" aria-label="订单关键词" @keyup.enter="loadOrders(true)">
|
||||
<template #prefix><Search :size="16" /></template>
|
||||
</el-input>
|
||||
<el-select v-model="filters.status" clearable placeholder="全部状态" aria-label="订单状态">
|
||||
<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<el-date-picker v-model="filters.dateRange" type="daterange" value-format="YYYY-MM-DD" range-separator="至" start-placeholder="创建开始" end-placeholder="创建结束" aria-label="订单创建日期" />
|
||||
</div>
|
||||
<div class="filter-actions">
|
||||
<el-button type="primary" plain :loading="loading" @click="loadOrders(true)"><Search :size="16" />查询租户</el-button>
|
||||
<el-button :disabled="loading" @click="resetFilters"><RotateCcw :size="16" />重置筛选</el-button>
|
||||
</div>
|
||||
</section>
|
||||
<QueryToolbar
|
||||
v-model="filters"
|
||||
ariaLabel="头程订单筛选"
|
||||
:fields="queryFields"
|
||||
search-text="查询订单"
|
||||
:search-on-reset="true"
|
||||
@search="searchOrders"
|
||||
/>
|
||||
|
||||
<el-alert v-if="loadError" type="error" :closable="false" show-icon role="alert">
|
||||
<template #title><div class="api-error-alert-title"><span>{{ loadError.message }}</span><ApiErrorMeta :details="loadError" /></div></template>
|
||||
<el-button v-if="tenantId" link type="danger" @click="loadOrders(true)">重新加载</el-button>
|
||||
</el-alert>
|
||||
<el-alert v-else type="info" :closable="false" show-icon>
|
||||
当前页面已直连 Order 服务。后端尚未提供平台代客创建、平台编辑及履约任务查询接口,因此相关操作暂不可用。
|
||||
<el-button link type="danger" @click="loadOrders">重新加载</el-button>
|
||||
</el-alert>
|
||||
|
||||
<section class="surface-panel table-panel">
|
||||
<header class="panel-heading"><div><h2>头程订单</h2><p>{{ loadedTenantId ? `当前数据范围:租户 ${loadedTenantId}` : '输入目标租户 ID 后读取 Order 服务真实数据' }}</p></div></header>
|
||||
<el-table v-if="loading || orders.length" v-loading="loading" :data="orders" row-key="id">
|
||||
<el-table-column label="操作" min-width="200" fixed="left">
|
||||
<template #default="{ row }"><div class="table-actions"><el-button link type="primary" @click="openDetail(row as PlatformFirstLegOrderResource)"><Eye :size="15" />详情</el-button><el-button v-if="actionLabel(row as PlatformFirstLegOrderResource)" link type="success" :loading="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @click="runLifecycleAction(row as PlatformFirstLegOrderResource)">{{ actionLabel(row as PlatformFirstLegOrderResource) }}</el-button><el-button v-if="canCancel(row as PlatformFirstLegOrderResource)" link type="danger" :loading="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @click="cancelOrder(row as PlatformFirstLegOrderResource)">取消</el-button><el-button v-if="can('platform:order:fulfillment') && !['DRAFT', 'REJECTED', 'CANCELLED'].includes((row as PlatformFirstLegOrderResource).status)" link type="primary" @click="openExpress(row as PlatformFirstLegOrderResource)"><PackageCheck :size="15" />快递</el-button><el-button v-if="can('platform:order:note')" link type="primary" @click="openNote(row as PlatformFirstLegOrderResource)"><FilePenLine :size="15" />备注</el-button></div></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单信息" min-width="210"><template #default="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).orderNo || '-' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).referenceId || '无客户参考号' }} · {{ formattedDate((row as PlatformFirstLegOrderResource).createdAt) }}</span></div></template></el-table-column>
|
||||
<el-table-column label="客户" min-width="190" show-overflow-tooltip><template #default="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).customerName }}</strong><span>租户 {{ (row as PlatformFirstLegOrderResource).tenantId }}</span></div></template></el-table-column>
|
||||
<el-table-column label="运输方案" min-width="180"><template #default="{ row }"><div class="primary-cell"><strong>{{ transportLabel(row as PlatformFirstLegOrderResource) }}</strong><span>{{ (row as PlatformFirstLegOrderResource).channelName || '未填写渠道' }}</span></div></template></el-table-column>
|
||||
<el-table-column label="目的地" min-width="150"><template #default="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).destinationWarehouseName || '-' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).destinationCountryCode || '-' }}</span></div></template></el-table-column>
|
||||
<el-table-column label="平台收货仓" min-width="180"><template #default="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).receivingWarehouseName || '-' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).receivingWarehouseAddress || '-' }}</span></div></template></el-table-column>
|
||||
<el-table-column label="履约快递" min-width="160"><template #default="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).expressCompany || '未维护' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).expressTrackingNo || '—' }}</span></div></template></el-table-column>
|
||||
<el-table-column label="状态" width="120"><template #default="{ row }"><StatusBadge :status="statusLabel((row as PlatformFirstLegOrderResource).status)" /></template></el-table-column>
|
||||
</el-table>
|
||||
<el-empty v-else :description="loadedTenantId ? '当前租户没有符合条件的头程订单' : '请先输入目标租户 ID 并查询'" />
|
||||
<footer class="table-footer"><span>共 {{ total }} 条</span><el-pagination v-model:current-page="page" :page-size="pageSize" :total="total" layout="prev, pager, next" @current-change="handlePageChange" /></footer>
|
||||
<header class="panel-heading"><div><h2>头程订单</h2><p>当前数据范围:一期固定租户 10001</p></div></header>
|
||||
<DataTable
|
||||
v-model:page="page"
|
||||
v-model:page-size="pageSize"
|
||||
:data="orders"
|
||||
:columns="orderColumns"
|
||||
:loading="loading"
|
||||
:total="total"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
empty-text="当前没有符合条件的头程订单"
|
||||
row-key="id"
|
||||
>
|
||||
<template #actions="{ row }"><div class="table-actions"><el-button link type="primary" @click="openDetail(row as PlatformFirstLegOrderResource)"><Eye :size="15" />详情</el-button><el-button v-if="actionLabel(row as PlatformFirstLegOrderResource)" link type="success" :loading="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @click="runLifecycleAction(row as PlatformFirstLegOrderResource)">{{ actionLabel(row as PlatformFirstLegOrderResource) }}</el-button><el-button v-if="canCancel(row as PlatformFirstLegOrderResource)" link type="danger" :loading="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @click="cancelOrder(row as PlatformFirstLegOrderResource)">取消</el-button><el-button v-if="can('platform:order:fulfillment') && !['DRAFT', 'REJECTED', 'CANCELLED'].includes((row as PlatformFirstLegOrderResource).status)" link type="primary" @click="openExpress(row as PlatformFirstLegOrderResource)"><PackageCheck :size="15" />快递</el-button><el-button v-if="can('platform:order:note')" link type="primary" @click="openNote(row as PlatformFirstLegOrderResource)"><FilePenLine :size="15" />备注</el-button></div></template>
|
||||
<template #orderInfo="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).orderNo || '-' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).referenceId || '无客户参考号' }} · {{ formattedDate((row as PlatformFirstLegOrderResource).createdAt) }}</span></div></template>
|
||||
<template #customer="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).customerName }}</strong><span>租户 {{ (row as PlatformFirstLegOrderResource).tenantId }}</span></div></template>
|
||||
<template #transport="{ row }"><div class="primary-cell"><strong>{{ transportLabel(row as PlatformFirstLegOrderResource) }}</strong><span>{{ (row as PlatformFirstLegOrderResource).channelName || '未填写渠道' }}</span></div></template>
|
||||
<template #destination="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).destinationWarehouseName || '-' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).destinationCountryCode || '-' }}</span></div></template>
|
||||
<template #receivingWarehouse="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).receivingWarehouseName || '-' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).receivingWarehouseAddress || '-' }}</span></div></template>
|
||||
<template #express="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).expressCompany || '未维护' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).expressTrackingNo || '—' }}</span></div></template>
|
||||
<template #status="{ row }"><StatusBadge :status="statusLabel((row as PlatformFirstLegOrderResource).status)" /></template>
|
||||
<template #empty><el-empty description="当前没有符合条件的头程订单" /></template>
|
||||
</DataTable>
|
||||
</section>
|
||||
|
||||
<el-drawer v-model="detailOpen" title="订单详情" size="760px" class="business-drawer">
|
||||
@@ -336,19 +364,17 @@ onMounted(() => {
|
||||
|
||||
<el-dialog v-model="expressDialogOpen" title="维护履约快递" width="520px">
|
||||
<el-alert title="当前后端契约只接收快递公司名称和快递单号;快递主数据关联待后端补充。" type="info" :closable="false" show-icon />
|
||||
<el-form label-position="top" class="delivery-form"><el-form-item label="快递公司" required><el-input v-model.trim="expressForm.expressCompany" maxlength="64" placeholder="例如 顺丰速运" /></el-form-item><el-form-item label="快递单号" required><el-input v-model.trim="expressForm.expressTrackingNo" maxlength="128" placeholder="请输入完整快递单号" /></el-form-item></el-form>
|
||||
<el-form ref="expressFormRef" :model="expressForm" :rules="expressRules" label-position="top" class="delivery-form"><el-form-item label="快递公司" prop="expressCompany" required><el-input v-model.trim="expressForm.expressCompany" maxlength="64" placeholder="例如 顺丰速运" /></el-form-item><el-form-item label="快递单号" prop="expressTrackingNo" required><el-input v-model.trim="expressForm.expressTrackingNo" maxlength="128" placeholder="请输入完整快递单号" /></el-form-item></el-form>
|
||||
<template #footer><el-button :disabled="expressSaving" @click="expressDialogOpen = false">取消</el-button><el-button type="primary" :loading="expressSaving" @click="saveExpress">保存快递信息</el-button></template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="noteDialogOpen" title="添加内部备注" width="520px">
|
||||
<el-form label-position="top"><el-form-item label="内部备注" required><el-input v-model.trim="noteContent" maxlength="2000" type="textarea" :rows="4" show-word-limit placeholder="仅平台内部可见" /></el-form-item></el-form>
|
||||
<el-form ref="noteFormRef" :model="noteForm" :rules="noteRules" label-position="top"><el-form-item label="内部备注" prop="content" required><el-input v-model.trim="noteForm.content" maxlength="2000" type="textarea" :rows="4" show-word-limit placeholder="仅平台内部可见" /></el-form-item></el-form>
|
||||
<template #footer><el-button :disabled="noteSaving" @click="noteDialogOpen = false">取消</el-button><el-button type="primary" :loading="noteSaving" @click="saveNote">保存备注</el-button></template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.server-order-filter-fields { grid-template-columns: minmax(150px, .65fr) minmax(220px, 1.2fr) minmax(150px, .75fr) minmax(260px, 1.1fr); }
|
||||
.party-grid p { margin: 4px 0 0; color: var(--cc-muted); font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; }
|
||||
@media (max-width: 720px) { .server-order-filter-fields { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user