master
lzq 2026-02-03 18:49:36 +08:00
parent 26f63b8af9
commit 5a8d2cc0db
24 changed files with 1001 additions and 200 deletions

View File

@ -0,0 +1,58 @@
import fs from 'fs'
import path from 'node:path'
import { colorSchemesConfig } from './color-schemes-config.ts'
const targetFile = path.resolve(__dirname, './color-schemes-config.ts')
function createStyl() {
const stylusFile = path.resolve(__dirname, '../src/assets/stylus/color.styl')
console.log('正在生成文件:', stylusFile)
let colorSchemes = []
for (let k1 in colorSchemesConfig) {
let colors = []
// @ts-ignore
for (let k2 in colorSchemesConfig[k1]) {
// @ts-ignore
colors.push(`${k2}: ${colorSchemesConfig[k1][k2]}`)
}
colorSchemes.push(` ${k1}: {\n ${colors.join(',\n ')}\n }`)
}
const stylContent = `colorSchemes = {\n${colorSchemes.join(',\n')}\n}
`
fs.writeFileSync(stylusFile, stylContent, {encoding: 'utf-8'})
}
function createTs() {
const tsFile = path.resolve(__dirname, '../src/common/utils/color-schemes.ts')
console.log('正在生成文件:', tsFile)
let colorSchemes = []
for (let k1 in colorSchemesConfig) {
let colors = []
// @ts-ignore
for (let k2 in colorSchemesConfig[k1]) {
// @ts-ignore
colors.push(`${k2}: '${colorSchemesConfig[k1][k2]}'`)
}
colorSchemes.push(` ${k1}: {\n ${colors.join(',\n ')}\n }`)
}
const tsContent = `export const colorSchemes = {\n${colorSchemes.join(',\n')}\n} as const
export type ColorSchemeType = keyof typeof colorSchemes
`
fs.writeFileSync(tsFile, tsContent, {encoding: 'utf-8'})
}
/**
*
*/
export default {
process(_: VitePluginTypes.FileWatcherProcessParam) {
createTs()
createStyl()
},
isAccept(data: VitePluginTypes.FileWatcherAcceptParam) {
return data.event === 'change' && !data.isDir && data.filePath === targetFile
},
} as VitePluginTypes.FileWatcherOptions

View File

@ -0,0 +1,84 @@
export const colorSchemesConfig = {
default: {
dark2: '#6A788F',
base: '#7987A1',
light3: '#8E9AB0',
light5: '#A3ABC0',
light7: '#B8C0D0',
light8: '#CCD5DF',
light9: '#E1E9EE',
},
primary: {
dark2: '#4A6FE6',
base: '#5D87FF',
light3: '#85A5FF',
light5: '#AAC0FF',
light7: '#C9D4FF',
light8: '#DCE4FF',
light9: '#EBF0FF',
},
success: {
dark2: '#38A85E',
base: '#4CB772',
light3: '#6FC78C',
light5: '#91D6A7',
light7: '#B3E5C1',
light8: '#D5F4DB',
light9: '#F7FFF6',
},
warning: {
dark2: '#E0A600',
base: '#F5B800',
light3: '#F9C733',
light5: '#FBD666',
light7: '#FDE599',
light8: '#FEF0BB',
light9: '#FFFAE0',
},
info: {
dark2: '#485263',
base: '#5A6578',
light3: '#747F91',
light5: '#8D97A6',
light7: '#A6AEBD',
light8: '#C0C6D2',
light9: '#D9DCE4',
},
danger: {
dark2: '#C93649',
base: '#E05F4D',
light3: '#F2998C',
light5: '#F7B8AF',
light7: '#FCD7D2',
light8: '#FFE6E5',
light9: '#FFF6F6',
},
ycz: {
dark2: '#9E547A',
base: '#C06F98',
light3: '#CD8AAD',
light5: '#DAA5C1',
light7: '#E6BED2',
light8: '#F0D4E2',
light9: '#F8E8F1',
},
dth: {
dark2: '#B83603',
base: '#E34303',
light3: '#FB5716',
light5: '#FC7642',
light7: '#FD956D',
light8: '#FDB498',
light9: '#FED4C3',
},
sch: {
dark2: '#BB2243',
base: '#ED556A',
light3: '#FA6175',
light5: '#FF798A',
light7: '#FF90A0',
light8: '#FFA8B7',
light9: '#FFC0CE',
},
}

View File

@ -0,0 +1,83 @@
colorSchemes = {
default: {
dark2: #6A788F,
base: #7987A1,
light3: #8E9AB0,
light5: #A3ABC0,
light7: #B8C0D0,
light8: #CCD5DF,
light9: #E1E9EE
},
primary: {
dark2: #4A6FE6,
base: #5D87FF,
light3: #85A5FF,
light5: #AAC0FF,
light7: #C9D4FF,
light8: #DCE4FF,
light9: #EBF0FF
},
success: {
dark2: #38A85E,
base: #4CB772,
light3: #6FC78C,
light5: #91D6A7,
light7: #B3E5C1,
light8: #D5F4DB,
light9: #F7FFF6
},
warning: {
dark2: #E0A600,
base: #F5B800,
light3: #F9C733,
light5: #FBD666,
light7: #FDE599,
light8: #FEF0BB,
light9: #FFFAE0
},
info: {
dark2: #485263,
base: #5A6578,
light3: #747F91,
light5: #8D97A6,
light7: #A6AEBD,
light8: #C0C6D2,
light9: #D9DCE4
},
danger: {
dark2: #C93649,
base: #E05F4D,
light3: #F2998C,
light5: #F7B8AF,
light7: #FCD7D2,
light8: #FFE6E5,
light9: #FFF6F6
},
ycz: {
dark2: #9E547A,
base: #C06F98,
light3: #CD8AAD,
light5: #DAA5C1,
light7: #E6BED2,
light8: #F0D4E2,
light9: #F8E8F1
},
dth: {
dark2: #B83603,
base: #E34303,
light3: #FB5716,
light5: #FC7642,
light7: #FD956D,
light8: #FDB498,
light9: #FED4C3
},
sch: {
dark2: #BB2243,
base: #ED556A,
light3: #FA6175,
light5: #FF798A,
light7: #FF90A0,
light8: #FFA8B7,
light9: #FFC0CE
}
}

View File

@ -23,8 +23,8 @@
}
.el-dialog {
max-height 90% !important
max-width 90% !important;
max-height 100% !important
max-width 100% !important;
margin 0 !important
box-sizing border-box !important
overflow: hidden;
@ -34,6 +34,7 @@
cursor move !important
display block
width 100%
text-align: start;
}

View File

@ -9,3 +9,4 @@
@import "scrollbar.styl"
@import "form.styl"
@import "input.styl"
@import "tag.styl"

View File

@ -1,85 +1,21 @@
@import "color.styl"
body {
/* Default */
--el-color-default: #7987A1 !important;
--el-color-default-light-3: #8E9AB0 !important;
--el-color-default-light-5: #A3ABC0 !important;
--el-color-default-light-7: #B8C0D0 !important;
--el-color-default-light-8: #CCD5DF !important;
--el-color-default-light-9: #E1E9EE !important;
--el-color-default-dark-2: #6A788F !important;
/* Primary */
--el-color-primary: #5D87FF !important;
--el-color-primary-light-3: #85A5FF !important;
--el-color-primary-light-5: #AAC0FF !important;
--el-color-primary-light-7: #C9D4FF !important;
--el-color-primary-light-8: #DCE4FF !important;
--el-color-primary-light-9: #EBF0FF !important;
--el-color-primary-dark-2: #4A6FE6 !important;
/* Success */
--el-color-success: #4CB772 !important;
--el-color-success-light-3: #6FC78C !important;
--el-color-success-light-5: #91D6A7 !important;
--el-color-success-light-7: #B3E5C1 !important;
--el-color-success-light-8: #D5F4DB !important;
--el-color-success-light-9: #F7FFF6 !important;
--el-color-success-dark-2: #38A85E !important;
/* Warning */
--el-color-warning: #F5B800 !important;
--el-color-warning-dark-2: #E0A600 !important;
--el-color-warning-light-3: #F9C733 !important;
--el-color-warning-light-5: #FBD666 !important;
--el-color-warning-light-7: #FDE599 !important;
--el-color-warning-light-8: #FEF0BB !important;
--el-color-warning-light-9: #FFFAE0 !important;
/* Info */
--el-color-info: #5A6578 !important;
--el-color-info-light-3: #747F91 !important;
--el-color-info-light-5: #8D97A6 !important;
--el-color-info-light-7: #A6AEBD !important;
--el-color-info-light-8: #C0C6D2 !important;
--el-color-info-light-9: #D9DCE4 !important;
--el-color-info-dark-2: #485263 !important;
/* Danger */
--el-color-danger: #E05F4D !important;
--el-color-danger-light-3: #F2998C !important;
--el-color-danger-light-5: #F7B8AF !important;
--el-color-danger-light-7: #FCD7D2 !important;
--el-color-danger-light-8: #FFE6E5 !important;
--el-color-danger-light-9: #FFF6F6 !important;
--el-color-danger-dark-2: #C93649 !important;
/* */
--el-color-ycz: #C06F98 !important;
--el-color-ycz-dark-2: #9E547A !important;
--el-color-ycz-light-3: #CD8AAD !important;
--el-color-ycz-light-5: #DAA5C1 !important;
--el-color-ycz-light-7: #E6BED2 !important;
--el-color-ycz-light-8: #F0D4E2 !important;
--el-color-ycz-light-9: #F8E8F1 !important;
/* */
--el-color-dth: #8C4B31 !important;
--el-color-dth-dark-2: #792808 !important;
--el-color-dth-light-3: #915D47 !important;
--el-color-dth-light-5: #946A5A !important;
--el-color-dth-light-7: #957568 !important;
--el-color-dth-light-8: #94796E !important;
--el-color-dth-light-9: #937B72 !important;
/**/
--el-color-sch: #ED556A !important;
--el-color-sch-light-3: #FA6175 !important;
--el-color-sch-light-5: #FF798A !important;
--el-color-sch-light-7: #FF90A0 !important;
--el-color-sch-light-8: #FFA8B7 !important;
--el-color-sch-light-9: #FFC0CE !important;
--el-color-sch-dark-2: #BB2243 !important;
for key, value in colorSchemes {
/*noinspection CssOverwrittenProperties*/
--el-color-{key}-dark-2: value.dark2 !important;
/*noinspection CssOverwrittenProperties*/
--el-color-{key}: value.base !important;
/*noinspection CssOverwrittenProperties*/
--el-color-{key}-light-3: value.light3 !important;
/*noinspection CssOverwrittenProperties*/
--el-color-{key}-light-5: value.light5 !important;
/*noinspection CssOverwrittenProperties*/
--el-color-{key}-light-7: value.light7 !important;
/*noinspection CssOverwrittenProperties*/
--el-color-{key}-light-8: value.light8 !important;
/*noinspection CssOverwrittenProperties*/
--el-color-{key}-light-9: value.light9 !important;
}
--el-font-weight-primary: 400 !important;
letter-spacing: .5px;

View File

@ -0,0 +1,8 @@
@import "color.styl"
for key, value in colorSchemes
.el-tag.el-tag--primary.el-tag[data-cs=\"{key}\"] {
--el-tag-text-color value.base !important
--el-tag-bg-color value.light9 !important
--el-tag-border-color value.light8 !important
--el-tag-hover-color value.base !important
}

View File

@ -0,0 +1,95 @@
export const colorSchemes = {
// 默认色(已完成)
default: {
dark2: '#6A788F',
base: '#7987A1',
light3: '#8E9AB0',
light5: '#A3ABC0',
light7: '#B8C0D0',
light8: '#CCD5DF',
light9: '#E1E9EE',
},
// 主色
primary: {
dark2: '#4A6FE6',
base: '#5D87FF',
light3: '#85A5FF',
light5: '#AAC0FF',
light7: '#C9D4FF',
light8: '#DCE4FF',
light9: '#EBF0FF',
},
// 成功色
success: {
dark2: '#38A85E',
base: '#4CB772',
light3: '#6FC78C',
light5: '#91D6A7',
light7: '#B3E5C1',
light8: '#D5F4DB',
light9: '#F7FFF6',
},
// 警告色
warning: {
dark2: '#E0A600',
base: '#F5B800',
light3: '#F9C733',
light5: '#FBD666',
light7: '#FDE599',
light8: '#FEF0BB',
light9: '#FFFAE0',
},
// 信息色
info: {
dark2: '#485263',
base: '#5A6578',
light3: '#747F91',
light5: '#8D97A6',
light7: '#A6AEBD',
light8: '#C0C6D2',
light9: '#D9DCE4',
},
// 危险色
danger: {
dark2: '#C93649',
base: '#E05F4D',
light3: '#F2998C',
light5: '#F7B8AF',
light7: '#FCD7D2',
light8: '#FFE6E5',
light9: '#FFF6F6',
},
// 樱草紫(已完成)
ycz: {
dark2: '#9E547A',
base: '#C06F98',
light3: '#CD8AAD',
light5: '#DAA5C1',
light7: '#E6BED2',
light8: '#F0D4E2',
light9: '#F8E8F1',
},
// 淡土黄
dth: {
dark2: '#B83603',
base: '#E34303',
light3: '#FB5716',
light5: '#FC7642',
light7: '#FD956D',
light8: '#FDB498',
light9: '#FED4C3',
},
// 山茶红
sch: {
dark2: '#BB2243',
base: '#ED556A',
light3: '#FA6175',
light5: '#FF798A',
light7: '#FF90A0',
light8: '#FFA8B7',
light9: '#FFC0CE',
},
} as const
export type ColorSchemeType = keyof typeof colorSchemes

View File

@ -54,7 +54,7 @@ const component = defineComponent(
</div>,
[ [ ElLoading.directive, loading.value ] ],
)),
footer: () => (<div>
footer: () => (<div class={styles.footer}>
{
slots.footer?.(detailData as D)
}

View File

@ -4,3 +4,12 @@
gap 20px
grid-template-columns 1fr
}
.footer {
width 100%
display flex
justify-content flex-end
gap 10px
padding 10px 0
}

View File

@ -621,6 +621,7 @@ const component = defineComponent(
cell-class-name="table-cell"
header-row-class-name="table-header"
class="data-table"
span-method={props.table.spanMethod}
onSort-change={sortChangeHandler}
>
{

View File

@ -86,24 +86,6 @@ declare global {
// for type re-export
declare global {
// @ts-ignore
export type {
Component,
Slot,
Slots,
ComponentPublicInstance,
ComputedRef,
DirectiveBinding,
ExtractDefaultPropTypes,
ExtractPropTypes,
ExtractPublicPropTypes,
InjectionKey,
PropType,
Ref,
ShallowRef,
MaybeRef,
MaybeRefOrGetter,
VNode,
WritableComputedRef,
} from 'vue'
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
}

View File

@ -0,0 +1,51 @@
<script lang="ts" setup>
import ADropTable from '@/components/a-drop-table/ADropTable.vue'
import DriverApi from '@/pages/cst/driver/driver-api.ts'
const props = defineProps<{
orgId?: string,
// modelValue: string,
}>()
const model = defineModel({type: String})
const dropTableColumns = [
{
label: '司机姓名',
prop: 'driverName',
},
{
label: '手机号',
prop: 'phone',
},
]
const dropTableLoader = (param: DriverTypes.SearchDriverParam) => {
console.log('props.orgId ==', props.orgId)
if (props.orgId == null) return Promise.resolve({
current: 1,
size: 10,
total: 0,
records: [] as any[],
} as G.PageResult<DriverTypes.SearchDriverResult>)
param.orgId = props.orgId
return DriverApi.paging(param).then(res => res.data)
}
/* const emits = defineEmits<{
'update:modelValue': [ value: string ]
}>() */
/* const driverId = computed({
get: () => model.value,
set: (val) => model.value = val,
}) */
</script>
<template>
<ADropTable v-model="model"
:columns="dropTableColumns"
:loader="dropTableLoader"
display-field="driverName"
placeholder="请选择司机"/>
</template>

View File

@ -0,0 +1,119 @@
<script lang="ts" setup>
import { transStatusColor } from '@/pages/order/constants.ts'
import Utils from '@/common/utils'
import AIcon from '@/components/a-icon/AIcon.vue'
const props = withDefaults(
defineProps<{
transRecodes?: OrderTypes.TransRecode[]
selectable?: boolean
}>(),
{
selectable: false,
transRecodes: () => [] as OrderTypes.TransRecode[],
},
)
const model = defineModel({type: Array as PropType<string[]>})
const selectRows = Utils.resetAble(reactive<string[]>([]))
const selectHeader_indeterminate = computed(() => {
return selectRows.length > 0 && selectRows.length < props.transRecodes.length
})
const selectHeader_checked = computed({
get() {
return selectRows.length === props.transRecodes.length
},
set(val) {
if (val) {
const newData = props.transRecodes.map(it => it.id)
selectRows.$reset([ ...new Set([ ...selectRows, ...newData ]) ] as string[])
} else {
const newData = props.transRecodes.map(it => it.id)
selectRows.$reset(selectRows.filter(it => !newData.includes(it)))
}
model.value = selectRows.$clone()
},
})
function rowClick(val: Record<string, any> & { id: string }) {
if (!props.selectable) {
return
}
const indexOf = selectRows.indexOf(val.id)
if (indexOf === -1) {
selectRows.push(val.id)
} else {
selectRows.splice(indexOf, 1)
}
model.value = selectRows.$clone()
}
</script>
<template>
<ElTable
:data="transRecodes"
cell-class-name="table-cell"
class="data-table"
empty-text="暂无数据"
header-row-class-name="table-header"
row-key="id"
@row-click="rowClick">
<ElTableColumn v-if="selectable" width="50">
<template #default="{row}">
<ElCheckbox :model-value="selectRows.includes(row.id)"/>
</template>
<template #header>
<ElCheckbox v-model="selectHeader_checked" :indeterminate="selectHeader_indeterminate"/>
</template>
</ElTableColumn>
<ElTableColumn label="车次" prop="trainNum"/>
<ElTableColumn label="运输状态" prop="transStatusTxt">
<template #default="{row}">
<ElTag :data-cs="transStatusColor.cs(row.transStatus)"> {{ row.transStatusTxt }}</ElTag>
</template>
</ElTableColumn>
<ElTableColumn label="司机姓名" prop="driverName"/>
<ElTableColumn label="司机电话" prop="driverPhone"/>
<ElTableColumn label="车牌号" prop="truckLicensePlate"/>
<ElTableColumn label="毛重" prop="truckLicensePlate"/>
<ElTableColumn label="皮重" prop="truckLicensePlate"/>
<ElTableColumn label="净重" prop="truckLicensePlate"/>
<ElTableColumn label="支付状态" prop="truckLicensePlate"/>
<ElTableColumn label="运输状态" prop="truckLicensePlate"/>
<ElTableColumn label="勘料状态" prop="truckLicensePlate"/>
<ElTableColumn label="操作" prop="action" width="150">
<div class="action-btn">
<ElButton plain type="success">
<AIcon name="approach"/>
</ElButton>
<ElButton plain type="danger">
<AIcon name="carexit"/>
</ElButton>
<ElButton plain type="warning">
<AIcon name="chakanliaodan"/>
</ElButton>
</div>
</ElTableColumn>
</ElTable>
</template>
<style lang="stylus" scoped>
.data-table {
width 100%
}
.action-btn {
width 100%;
display flex;
justify-content space-between;
align-items center;
:deep(.el-button) {
width 32px;
height 32px;
padding 0;
}
}
</style>

View File

@ -3,14 +3,16 @@
ref="tablePage"
v-bind="tablePageProps">
<template #highFormItem="formData">
<ElFormItem label="站点">
<ElInput v-model="formData.stationId" placeholder="站点"/>
</ElFormItem>
<ElFormItem label="订单编号">
<ElInput v-model="formData.sn" placeholder="订单编号"/>
</ElFormItem>
<ElFormItem label="项目名称">
<ElInput v-model="formData.projectName" placeholder="项目名称"/>
<ElFormItem label="订单状态">
<ElSelect v-model="formData.orderStatus" placeholder="订单状态">
<ElOption v-for="item in orderStatus" :key="item.val" :label="item.txt" :value="item.val"/>
</ElSelect>
</ElFormItem>
<ElFormItem label="收纳站点">
<ElInput v-model="formData.stationId" placeholder="站点"/>
</ElFormItem>
<ElFormItem label="客户姓名">
<ElInput v-model="formData.contacts" placeholder="客户姓名"/>
@ -18,16 +20,12 @@
<ElFormItem label="联系方式">
<ElInput v-model="formData.phone" placeholder="联系方式"/>
</ElFormItem>
<ElFormItem label="订单类型">
<ElInput v-model="formData.orderCategory" placeholder="订单类型"/>
</ElFormItem>
<!-- <ElFormItem label="订单状态">
<ElInput v-model="formData.orderStatus" placeholder="订单状态"/>
</ElFormItem> -->
<ElFormItem label="运输企业">
<ElInput v-model="formData.transOrgName" placeholder="运输企业"/>
</ElFormItem>
<ElFormItem label="项目名称">
<ElInput v-model="formData.projectName" placeholder="项目名称"/>
</ElFormItem>
<ElFormItem label="下单时间">
<ADtPicker v-model="formData.orderTimes" :change-handler="research"/>
</ElFormItem>
@ -37,10 +35,12 @@
</template>
<template #simpleFormItem="formData">
<ElFormItem>
<ElInput v-model="formData.sn" placeholder="订单编号"/>
<ElSelect v-model="formData.orderStatus" placeholder="订单状态">
<ElOption v-for="item in orderStatus" :key="item.val" :label="item.txt" :value="item.val"/>
</ElSelect>
</ElFormItem>
<ElFormItem>
<ElInput v-model="formData.orderCategory" placeholder="订单类型"/>
<ElInput v-model="formData.sn" placeholder="订单编号"/>
</ElFormItem>
</template>
<template #columns>
@ -50,7 +50,7 @@
<!-- <ElTableColumn label="联系方式" prop="phone"/> -->
<ElTableColumn label="货品名称" prop="goodsName" width="120"/>
<ElTableColumn label="项目名称" show-overflow-tooltip width="100">
<ElTableColumn label="项目名称" prop="projectName" show-overflow-tooltip width="100">
<template #default="{row}">
{{ row.projectName ?? '-' }}
</template>
@ -81,6 +81,7 @@
</template>
<BookForm ref="bookForm" :research="research"/>
<BookDetail ref="bookDetail"/>
<DispatchForm ref="dispatchForm"/>
</ATablePage>
</template>
@ -93,10 +94,12 @@ import ATablePage, {
} from '@/components/a-page/a-table-page/ATablePage.tsx'
import {
orderCategory,
orderStatus,
transStatus,
} from '@/pages/order/constants.ts'
import BookDetail from '@/pages/order/book/BookDetail.vue'
import type { R } from '@/common/utils/http-util.ts'
import DispatchForm from '@/pages/order/book/DispatchForm.vue'
const props = defineProps<{
defaultOrderCategory: typeof orderCategory[number]['val']
@ -105,14 +108,17 @@ const props = defineProps<{
const tablePageIns = useTemplateRef<ATablePageInstance>('tablePage')
const bookFormIns = useTemplateRef<InstanceType<typeof BookForm>>('bookForm')
const bookDetailIns = useTemplateRef<InstanceType<typeof BookDetail>>('bookDetail')
const dispatchFormIns = useTemplateRef<InstanceType<typeof DispatchForm>>('dispatchForm')
function research() {
tablePageIns.value?.doSearch()
}
const spanColumn = [ 'sn', 'contacts', 'goodsName', 'projectName', 'stationName', 'transOrgName', 'tableAction' ]
const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTypes.TableData>({
pageLayout: {
dataListHeight: 3,
searchFormHeight: '180px',
dataListHeight: 1,
},
searchForm: {
defaultData: {
@ -120,6 +126,11 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
},
highForm: {
contentWidth: 342,
cgap: 20,
rgap: 20,
},
simpleForm: {
colCount: 2,
},
/* paging(param: OrderTypes.SearchOrderParam) {
return OrderApi.paging(param)
@ -151,7 +162,29 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
total: 100,
records: [
{
rowCount: 1,
rowCount: 2,
id: '123',
sn: '202308240001',
orderTime: '2023-08-24 10:00:00',
contacts: '张三',
phone: '13800000000',
projectName: '项目A',
stationName: '站点B',
goodsName: '商品X',
unit: '吨',
customerMemo: '客户备注',
estimatedQuantity: 100,
estimatedTrainNum: 2,
transDistance: 500,
orderCategoryTxt: '订单类型A',
transOrgName: '运输公司',
transStatusTxt: '运输中',
transStatus: 'DaiPaiDan',
checkStatusTxt: '未勘料',
paymentStatusTxt: '未支付',
} as OrderTypes.TableData,
{
rowCount: 0,
id: '123',
sn: '202308240001',
orderTime: '2023-08-24 10:00:00',
@ -188,6 +221,18 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
],
},
table: {
spanMethod({row, column}) {
if (!spanColumn.includes(column.property)) {
return {
rowspan: 1,
colspan: 1,
}
}
return {
rowspan: row.rowCount,
colspan: 1,
}
},
actionColumn: {
tableActions: [
{
@ -195,6 +240,7 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
icon: 'Postcard',
type: 'primary',
action({row}) {
console.log(row)
bookDetailIns.value?.open(row)
},
},
@ -206,7 +252,11 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
},
icon: 'Position',
action({row}) {
bookDetailIns.value?.open(row)
dispatchFormIns.value?.open({
orderId: row.id,
sn: row.sn,
transOrgId: row.transOrgId,
})
},
},
],

View File

@ -1,68 +1,55 @@
<template>
<ADetailPanel
ref="detailPanel"
class="book-detail-panel"
v-bind="detailPanelProps">
<template #default="detailData">
<ElDescriptions border class="description" title="订单信息">
<ElDescriptions :column="4" :title="'订单信息(' + detailData.orderCategoryTxt+''" border class="description">
<ElDescriptionsItem label="订单编号">
{{ detailData.sn }}
</ElDescriptionsItem>
<ElDescriptionsItem label="产品名称">
{{ detailData.goodsName }}
</ElDescriptionsItem>
<ElDescriptionsItem label="下单时间">
{{ detailData.orderTime }}
</ElDescriptionsItem>
<ElDescriptionsItem label="项目名称">
{{ detailData.projectInfo?.projectName || '-' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="站点名称">
{{ detailData.stationName }}
</ElDescriptionsItem>
<ElDescriptionsItem label="预估量">
{{ detailData.estimatedQuantity + ' ' + (detailData.unitTxt ?? '') }}
</ElDescriptionsItem>
<ElDescriptionsItem label="预估车数">
{{ detailData.estimatedTrainNum }}
</ElDescriptionsItem>
<ElDescriptionsItem label="运距">
{{ detailData.transDistance }} 公里
</ElDescriptionsItem>
<ElDescriptionsItem label="客户姓名">
{{ detailData.contacts }}
</ElDescriptionsItem>
<ElDescriptionsItem label="客户电话">
{{ detailData.phone }}
</ElDescriptionsItem>
<ElDescriptionsItem label="项目名称">
{{ detailData.projectInfo?.projectName || '-' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="站点名称">
{{ detailData.stationName }}
</ElDescriptionsItem>
<ElDescriptionsItem label="产品名称">
{{ detailData.goodsName }}
</ElDescriptionsItem>
<ElDescriptionsItem label="计量单位">
{{ detailData.unit }}
</ElDescriptionsItem>
<ElDescriptionsItem label="客户备注">
<ElDescriptionsItem :span="2" label="客户备注">
{{ detailData.customerMemo }}
</ElDescriptionsItem>
<ElDescriptionsItem label="预估量">
{{ detailData.estimatedQuantity }}
</ElDescriptionsItem>
<ElDescriptionsItem label="预估车数">
{{ detailData.estimatedTrainNum }}
</ElDescriptionsItem>
<ElDescriptionsItem label="运距(米)">
{{ detailData.transDistance }}
</ElDescriptionsItem>
<ElDescriptionsItem label="订单类型">
{{ detailData.orderCategoryTxt }}
</ElDescriptionsItem>
</ElDescriptions>
<ElDescriptions class="description" direction="vertical" title="运输信息">
<ElDescriptionsItem>
<ElTable
:data="detailData.transRecodes"
cell-class-name="table-cell"
class="data-table"
header-row-class-name="table-header">
<ElTableColumn label="车次" prop="trainNum"/>
<ElTableColumn label="运输状态" prop="transStatusTxt"/>
<ElTableColumn label="司机姓名" prop="driverName"/>
<ElTableColumn label="司机电话" prop="driverPhone"/>
<ElTableColumn label="车牌号" prop="truckLicensePlate"/>
</ElTable>
<ElDescriptions :column="1" class="description" direction="vertical" title="运输信息">
<ElDescriptionsItem :span="1">
<TransRecode v-model="transIds" :selectable="true" :trans-recodes="detailData.transRecodes"/>
</ElDescriptionsItem>
</ElDescriptions>
</template>
<template #footer>
<ElButton type="primary" @click="dispatch"></ElButton>
<template #footer="detailData">
<ElButton :disabled="transIds.length<1" type="primary" @click="dispatch(detailData)"></ElButton>
<DispatchForm ref="dispatchForm"/>
</template>
</ADetailPanel>
</template>
@ -72,20 +59,20 @@ import ADetailPanel, {
type ADetailPanelInstance,
buildDetailPanelProps,
} from '@/components/a-detail-panel/ADetailPanel.tsx'
import { ElMessageBox } from 'element-plus'
import TransRecode from '@/pages/order/TransRecode.vue'
import DispatchForm from '@/pages/order/book/DispatchForm.vue'
const detailPanelIns = useTemplateRef<ADetailPanelInstance<OrderTypes.TableData>>('detailPanel')
const dispatchFormIns = useTemplateRef<InstanceType<typeof DispatchForm>>('dispatchForm')
function dispatch() {
console.log('派单')
ElMessageBox({
title: '请选择司机',
message: h('p', null, [
h('input', {
type: 'text',
placeholder: '请输入司机姓名',
}),
]),
const transIds = ref([] as string[])
function dispatch(data: OrderTypes.SearchOrderResult) {
dispatchFormIns.value?.open({
orderId: data.id,
sn: data.sn,
transIds: transIds.value,
transOrgId: data.transOrgId,
})
}
@ -107,6 +94,7 @@ const detailPanelProps = buildDetailPanelProps<OrderTypes.SearchOrderResult>({
stationName: '站点B',
goodsName: '商品X',
unit: '吨',
transOrgId: '1',
customerMemo: '客户备注',
estimatedQuantity: 100,
estimatedTrainNum: 2,
@ -114,18 +102,64 @@ const detailPanelProps = buildDetailPanelProps<OrderTypes.SearchOrderResult>({
orderCategoryTxt: '订单类型A',
transRecodes: [
{
id: '1',
transStatus: 'DaiPaiDan',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '2',
transStatus: 'DaiJieDan',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '3',
transStatus: 'YiJieDan',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '4',
transStatus: 'YunShuZhong',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '5',
transStatus: 'YiJinChang',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '6',
transStatus: 'YiChuChang',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '7',
transStatus: 'YiWanCheng',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '8',
transStatus: 'YiQuXiao',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
@ -138,7 +172,6 @@ const detailPanelProps = buildDetailPanelProps<OrderTypes.SearchOrderResult>({
},
// detailsLoader: OrderApi.detail,
})
defineExpose({
open(data: OrderTypes.TableData) {
detailPanelIns.value?.open(data)
@ -148,6 +181,8 @@ defineExpose({
<style lang="stylus" scoped>
.description {
.data-table {
height 250px !important
}
}
</style>

View File

@ -0,0 +1,80 @@
<script lang="ts" setup>
import DriverDropTable from '@/pages/cst/driver/DriverDropTable.vue'
import AFormPanel, {
type AFormPanelInstance,
buildFormPanelProps,
} from '@/components/a-form-panel/AFormPanel.tsx'
import OrderApi from '@/pages/order/order-api.ts'
const formPanelIns = useTemplateRef<AFormPanelInstance>('formPanel')
let orderId: string | undefined = undefined
let transIds: string[] | undefined = undefined
let transOrgId = ref<string | undefined>(undefined)
let sn = ref<string | undefined>(undefined)
const formPanelProps = buildFormPanelProps<OrderTypes.DispatchParam>({
title: '派单',
labelWidth: '0',
detailsLoader() {
return Promise.resolve({})
},
doSubmit(data) {
return OrderApi.dispatch({
orderId: orderId!,
transIds: transIds!,
driverId: data.driverId,
})
.then(() => true)
},
rules: () => {
return {
driverId: [ {required: true, message: '选择司机', trigger: 'blur'} ],
}
},
})
defineExpose({
open(data: OrderTypes.DispatchParam) {
orderId = data.orderId
transIds = data.transIds
transOrgId.value = data.transOrgId
sn.value = data.sn
formPanelIns.value?.open()
},
})
</script>
<template>
<AFormPanel
ref="formPanel"
v-bind="formPanelProps">
<template #default="formData">
<div class="form-items">
<div class="form-items-sn">单号{{ sn }}</div>
<ElFormItem label=" " prop="driverId">
<DriverDropTable v-model="formData.driverId" :org-id="transOrgId"/>
</ElFormItem>
</div>
</template>
</AFormPanel>
</template>
<style lang="stylus" scoped>
.form-items {
grid-template-columns: 1fr;
padding 0 !important
:deep(.el-form-item__content) {
margin unset !important
}
.form-items-sn {
margin: 0 0 16px 0;
text-align: center;
font-size: 16px;
font-weight: 600;
}
}
</style>

View File

@ -4,6 +4,14 @@ export {}
declare global {
namespace OrderTypes {
interface DispatchParam {
orderId?: string
transIds?: string[]
driverId?: string
transOrgId?: string
sn?: string
}
interface SearchOrderParam extends G.PageParam {
// 订单编号
sn?: string
@ -278,7 +286,7 @@ declare global {
transStatusTxt?: string
checkStatus?: string
checkStatusTxt?: string
transOrgId?: string
}

View File

@ -1,4 +1,5 @@
import { createEnum } from '@/common/utils/enums.ts'
import type { ColorSchemeType } from '@/common/utils/color-schemes.ts'
const orderCategoryList = [
{
@ -75,6 +76,26 @@ const transStatusList = [
},
] as const
export const transStatus = createEnum(transStatusList)
export const transStatusColor: {
cs: (data?: any, defaultColorScheme?: ColorSchemeType | '') => ColorSchemeType | ''
} & {
[key in typeof transStatusList[number]['val']]: ColorSchemeType
} = {
DaiPaiDan: 'primary',
DaiJieDan: 'warning',
YiJieDan: 'dth',
YunShuZhong: 'success',
YiJinChang: 'ycz',
YiChuChang: 'sch',
YiWanCheng: 'danger',
YiQuXiao: 'info',
cs(data?: any, defaultColorScheme: ColorSchemeType | '' = '') {
if (data) {
return this[data as typeof transStatusList[number]['val']]
}
return defaultColorScheme
},
}
const checkStatusList = [
{

View File

@ -191,14 +191,14 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
bookDetailIns.value?.open(row)
},
},
{
tooltip: '历史轨迹',
type: 'info',
icon: 'liandan',
action({row}) {
bookDetailIns.value?.open(row)
},
},
/* {
tooltip: '历史轨迹',
type: 'info',
icon: 'liandan',
action({row}) {
bookDetailIns.value?.open(row)
},
}, */
],
},
},

View File

@ -19,6 +19,9 @@ export default {
del(ids: string[]) {
return post("/order/del", ids);
},
dispatch(data: OrderTypes.DispatchParam) {
return post('/order/dispatch', data)
},
assignmentOrg(data: any) {
return post("/order/assignmentOrg", data);
},

View File

@ -80,7 +80,7 @@
<!-- <ElTableColumn label="客户备注" prop="customerMemo"/> -->
</template>
<OrderForm ref="orderForm" :research="research"/>
<BookDetail ref="bookDetail"/>
<RealtimeDetail ref="realtimeDetail"/>
<InOutPanel ref="inOutPanel"/>
</ATablePage>
</template>
@ -92,7 +92,6 @@ import ATablePage, {
type ATablePageInstance,
buildTablePageProps,
} from '@/components/a-page/a-table-page/ATablePage.tsx'
import BookDetail from '@/pages/order/book/BookDetail.vue'
import {
checkStatus,
orderCategory,
@ -102,12 +101,13 @@ import InOutPanel from '@/pages/order/realtime/InOutPanel.vue'
import { ElMessage } from 'element-plus'
import { useTemplateRef } from 'vue'
import type { R } from '@/common/utils/http-util.ts'
import RealtimeDetail from '@/pages/order/realtime/RealtimeDetail.vue'
const props = defineProps<{
defaultOrderCategory: typeof orderCategory[number]['val']
}>()
const tablePageIns = useTemplateRef<ATablePageInstance>('tablePage')
const bookDetailIns = useTemplateRef<InstanceType<typeof BookDetail>>('bookDetail')
const realtimeDetailIns = useTemplateRef<InstanceType<typeof RealtimeDetail>>('realtimeDetail')
const inOutPanelIns = useTemplateRef<InstanceType<typeof InOutPanel>>('inOutPanel')
function research() {
@ -230,7 +230,7 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
},
table: {
actionColumn: {
width: 190,
width: 150,
foldLimit: 5,
tableActions: [
{
@ -238,7 +238,7 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
icon: 'Postcard',
type: 'primary',
action({row}) {
bookDetailIns.value?.open(row)
realtimeDetailIns.value?.open(row)
},
},
{
@ -246,17 +246,17 @@ const tablePageProps = buildTablePageProps<OrderTypes.SearchOrderParam, OrderTyp
type: 'info',
icon: 'liandan',
action({row}) {
bookDetailIns.value?.open(row)
},
},
{
tooltip: '实时轨迹',
type: 'info',
icon: 'liandan',
action({row}) {
bookDetailIns.value?.open(row)
realtimeDetailIns.value?.open(row)
},
},
/* {
tooltip: '实时轨迹',
type: 'info',
icon: 'liandan',
action({row}) {
bookDetailIns.value?.open(row)
},
}, */
{
tooltip: '进场',
type: 'success',

View File

@ -0,0 +1,175 @@
<template>
<ADetailPanel
ref="detailPanel"
class="book-detail-panel"
v-bind="detailPanelProps">
<template #default="detailData">
<ElDescriptions :column="4" :title="'订单信息(' + detailData.orderCategoryTxt+''" border class="description">
<ElDescriptionsItem label="订单编号">
{{ detailData.sn }}
</ElDescriptionsItem>
<ElDescriptionsItem label="产品名称">
{{ detailData.goodsName }}
</ElDescriptionsItem>
<ElDescriptionsItem label="下单时间">
{{ detailData.orderTime }}
</ElDescriptionsItem>
<ElDescriptionsItem label="项目名称">
{{ detailData.projectInfo?.projectName || '-' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="站点名称">
{{ detailData.stationName }}
</ElDescriptionsItem>
<ElDescriptionsItem label="预估量">
{{ detailData.estimatedQuantity + ' ' + (detailData.unitTxt ?? '') }}
</ElDescriptionsItem>
<ElDescriptionsItem label="预估车数">
{{ detailData.estimatedTrainNum }}
</ElDescriptionsItem>
<ElDescriptionsItem label="运距">
{{ detailData.transDistance }} 公里
</ElDescriptionsItem>
<ElDescriptionsItem label="客户姓名">
{{ detailData.contacts }}
</ElDescriptionsItem>
<ElDescriptionsItem label="客户电话">
{{ detailData.phone }}
</ElDescriptionsItem>
<ElDescriptionsItem :span="2" label="客户备注">
{{ detailData.customerMemo }}
</ElDescriptionsItem>
</ElDescriptions>
<ElDescriptions :column="1" class="description" direction="vertical" title="运输信息">
<ElDescriptionsItem :span="1">
<TransRecode :trans-recodes="detailData.transRecodes"/>
</ElDescriptionsItem>
</ElDescriptions>
</template>
</ADetailPanel>
</template>
<script lang="ts" setup>
import ADetailPanel, {
type ADetailPanelInstance,
buildDetailPanelProps,
} from '@/components/a-detail-panel/ADetailPanel.tsx'
import TransRecode from '@/pages/order/TransRecode.vue'
import DispatchForm from '@/pages/order/book/DispatchForm.vue'
const detailPanelIns = useTemplateRef<ADetailPanelInstance<OrderTypes.TableData>>('detailPanel')
const dispatchFormIns = useTemplateRef<InstanceType<typeof DispatchForm>>('dispatchForm')
const transIds = ref([] as string[])
const detailPanelProps = buildDetailPanelProps<OrderTypes.SearchOrderResult>({
title: '订单详情',
width: '80vw',
detailsLoader: () => {
return Promise.resolve({
code: 200,
data: {
id: '123',
sn: '202308240001',
orderTime: '2023-08-24 10:00:00',
contacts: '张三',
phone: '13800000000',
projectInfo: {
projectName: '项目A',
},
stationName: '站点B',
goodsName: '商品X',
unit: '吨',
transOrgId: '1',
customerMemo: '客户备注',
estimatedQuantity: 100,
estimatedTrainNum: 2,
transDistance: 500,
orderCategoryTxt: '订单类型A',
transRecodes: [
{
id: '1',
transStatus: 'DaiPaiDan',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '2',
transStatus: 'DaiJieDan',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '3',
transStatus: 'YiJieDan',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '4',
transStatus: 'YunShuZhong',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '5',
transStatus: 'YiJinChang',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '6',
transStatus: 'YiChuChang',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '7',
transStatus: 'YiWanCheng',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
}, {
id: '8',
transStatus: 'YiQuXiao',
trainNum: '车次1',
transStatusTxt: '运输中',
driverName: '司机A',
driverPhone: '13900000000',
truckLicensePlate: '粤B12345',
},
],
},
})
},
// detailsLoader: OrderApi.detail,
})
defineExpose({
open(data: OrderTypes.TableData) {
detailPanelIns.value?.open(data)
},
})
</script>
<style lang="stylus" scoped>
.description {
.data-table {
height 250px !important
}
}
</style>

View File

@ -15,6 +15,7 @@ import ElementPlus from 'unplugin-element-plus/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { fileWatcher } from './plugin/file-watcher.ts'
import IconfontProcess from './plugin/iconfont-process.ts'
import ColorProcess from './plugin/color-process.ts'
// https://vite.dev/config/
export default defineConfig((configEnv) => {
@ -47,7 +48,7 @@ export default defineConfig((configEnv) => {
resolvers: [ ElementPlusResolver() ],
}),
processHtml(env.VITE_APP_NAME),
fileWatcher(IconfontProcess),
fileWatcher(IconfontProcess, ColorProcess),
zipDist(),
],
resolve: {