客户管理

master
lzq 2026-01-23 14:45:59 +08:00
parent ee3a206003
commit ad658e16d3
13 changed files with 355 additions and 272 deletions

View File

@ -49,7 +49,6 @@ const enableRender = ref(false)
let moveHandle = useMove(id)
function openedHandler() {
console.log('ADialog opened', id)
const modal = document.querySelector('.' + modalClass)
let container = modal?.querySelector('.el-overlay-dialog') as HTMLElement
let dialog = container?.querySelector('.draggable-dialog') as HTMLElement
@ -63,7 +62,6 @@ function openedHandler() {
}
function closedHandler() {
console.log('ADialog closed', id)
moveHandle
.disable()
.setContainer()
@ -72,15 +70,12 @@ function closedHandler() {
}
onMounted(() => {
console.log('ADialog mounted', id)
enableRender.value = true
})
onActivated(() => {
console.log('ADialog activated', id)
moveHandle.enable()
})
onUnmounted(() => {
console.log('ADialog unmounted', id)
moveHandle.destroy()
})

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* 项目名称 再昇云 */
src: url('@/components/a-icon/iconfont.woff2?t=1768642091253') format('woff2'),
url('@/components/a-icon/iconfont.woff?t=1768642091253') format('woff'),
url('@/components/a-icon/iconfont.ttf?t=1768642091253') format('truetype');
src: url('@/components/a-icon/iconfont.woff2?t=1769142012944') format('woff2'),
url('@/components/a-icon/iconfont.woff?t=1769142012944') format('woff'),
url('@/components/a-icon/iconfont.ttf?t=1769142012944') format('truetype');
}
.iconfont {
@ -13,6 +13,42 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-dianhua-1:before {
content: "\e65d";
}
.icon-weixin:before {
content: "\e65a";
}
.icon-yue:before {
content: "\e65b";
}
.icon-yuejie:before {
content: "\e65c";
}
.icon-siji:before {
content: "\e659";
}
.icon-icon-cart:before {
content: "\e656";
}
.icon-yunshu:before {
content: "\e657";
}
.icon-kehu:before {
content: "\e658";
}
.icon-xiaonachang:before {
content: "\e7aa";
}
.icon-home-3-line:before {
content: "\e6b3";
}

View File

@ -5,6 +5,69 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "1272171",
"name": "电话",
"font_class": "dianhua-1",
"unicode": "e65d",
"unicode_decimal": 58973
},
{
"icon_id": "933713",
"name": "微信",
"font_class": "weixin",
"unicode": "e65a",
"unicode_decimal": 58970
},
{
"icon_id": "2681721",
"name": "余额",
"font_class": "yue",
"unicode": "e65b",
"unicode_decimal": 58971
},
{
"icon_id": "5351377",
"name": "月结",
"font_class": "yuejie",
"unicode": "e65c",
"unicode_decimal": 58972
},
{
"icon_id": "19586478",
"name": "司机",
"font_class": "siji",
"unicode": "e659",
"unicode_decimal": 58969
},
{
"icon_id": "712236",
"name": "采购",
"font_class": "icon-cart",
"unicode": "e656",
"unicode_decimal": 58966
},
{
"icon_id": "12975022",
"name": "运输",
"font_class": "yunshu",
"unicode": "e657",
"unicode_decimal": 58967
},
{
"icon_id": "31312998",
"name": "客户",
"font_class": "kehu",
"unicode": "e658",
"unicode_decimal": 58968
},
{
"icon_id": "45748068",
"name": "消纳场",
"font_class": "xiaonachang",
"unicode": "e7aa",
"unicode_decimal": 59306
},
{
"icon_id": "17102563",
"name": "home-3-line",

View File

@ -5,6 +5,69 @@ export const icons = {
'css_prefix_text': 'icon-',
'description': '',
'glyphs': [
{
'icon_id': '1272171',
'name': '电话',
'font_class': 'dianhua-1',
'unicode': 'e65d',
'unicode_decimal': 58973,
},
{
'icon_id': '933713',
'name': '微信',
'font_class': 'weixin',
'unicode': 'e65a',
'unicode_decimal': 58970,
},
{
'icon_id': '2681721',
'name': '余额',
'font_class': 'yue',
'unicode': 'e65b',
'unicode_decimal': 58971,
},
{
'icon_id': '5351377',
'name': '月结',
'font_class': 'yuejie',
'unicode': 'e65c',
'unicode_decimal': 58972,
},
{
'icon_id': '19586478',
'name': '司机',
'font_class': 'siji',
'unicode': 'e659',
'unicode_decimal': 58969,
},
{
'icon_id': '712236',
'name': '采购',
'font_class': 'icon-cart',
'unicode': 'e656',
'unicode_decimal': 58966,
},
{
'icon_id': '12975022',
'name': '运输',
'font_class': 'yunshu',
'unicode': 'e657',
'unicode_decimal': 58967,
},
{
'icon_id': '31312998',
'name': '客户',
'font_class': 'kehu',
'unicode': 'e658',
'unicode_decimal': 58968,
},
{
'icon_id': '45748068',
'name': '消纳场',
'font_class': 'xiaonachang',
'unicode': 'e7aa',
'unicode_decimal': 59306,
},
{
'icon_id': '17102563',
'name': 'home-3-line',

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,6 +4,7 @@ import Page from '@/components/page/Page.vue'
import Utils, { type ResetAble } from '@/common/utils'
import Colls from '@/common/utils/colls.ts'
import Strings from '@/common/utils/strings.ts'
import { saveFile } from '@/common/app'
import type { R } from '@/common/utils/http-util.ts'
import type {
TableColumnCtx,
@ -13,6 +14,7 @@ import type { DefaultRow } from 'element-plus/es/components/table/src/table/defa
import type {
ActionColumnType,
FormPropsType,
TableActionType,
TablePropsType,
ToolType,
} from '@/components/page/a-page-type.ts'
@ -27,6 +29,7 @@ const props = withDefaults(
rightTools?: Required<Omit<ToolType, 'type' | 'label'>>[]
tableProps?: TablePropsType<TT, F>
searchFormProps?: FormPropsType
exportHandler?: (param: F) => Promise<R<{ content: Blob, filename: string }>>
simpleSearchFormProps?: FormPropsType
formStyle?: {
border: boolean
@ -106,6 +109,23 @@ function doSearch() {
}
}
function doExport() {
if (props.exportHandler == null) {
return
}
loading.value = true
props.exportHandler(searchForm.$clone() as F)
.then((res) => {
const {content, filename} = res.data ?? {}
if (content != null && filename != null) {
saveFile(content, filename)
}
})
.finally(() => {
loading.value = false
})
}
function showSearchFormHandle() {
showSearchForm.value = !showSearchForm.value
searchForm.$reset()
@ -174,10 +194,10 @@ onMounted(doSearch)
doReset()
}
}">
<ElButton :icon="elIcons.Refresh" :loading="loading" type="default"/>
<ElButton :icon="elIcons.Search" :loading="loading" type="default"/>
<template #dropdown>
<ElDropdownMenu slot="dropdown">
<ElDropdownItem :icon="elIcons.Search" command="reset">重置并刷新</ElDropdownItem>
<ElDropdownItem :icon="elIcons.Refresh" command="reset">重置并刷新</ElDropdownItem>
</ElDropdownMenu>
</template>
</ElDropdown>
@ -187,6 +207,9 @@ onMounted(doSearch)
:icon="elIcons[tool.icon]"
@click="tool.action"/>
</template>
<ElTooltip v-if="exportHandler != null" content="导出" placement="top">
<ElButton :icon="elIcons.Download" :loading="loading" type="default" @click="doExport"/>
</ElTooltip>
<ElTooltip :content="showSearchForm?'关闭高级搜索':'打开高级搜索'" placement="top">
<ElButton :class="{'filter-btn-active':showSearchForm} " :icon="elIcons.Filter" type="default" @click="showSearchFormHandle"/>
</ElTooltip>
@ -210,7 +233,7 @@ onMounted(doSearch)
<ElTableColumn v-if="!Colls.isEmpty(actionColumn)" :width="actionColumn?.width?? '180'" fixed="right" label="操作">
<template #default="scope">
<div class="action-btn">
<template v-for="(tableAction,i) in actionColumn!.tableActions.filter(it=>(it.show??true))" :key="'action-btn-'+i">
<template v-for="(tableAction,i) in actionColumn!.tableActions.filter(it=>(it.show==null?true:it.show(scope)))" :key="'action-btn-'+i">
<ElPopconfirm
v-if="tableAction.confirm != null"
:cancel-button-text="tableAction.confirm.cancelButtonText?? '否'"

View File

@ -1,123 +0,0 @@
/* eslint-disable */
// @ts-nocheck
// biome-ignore lint: disable
// oxlint-disable
// ------
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
import { GlobalComponents } from 'vue'
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
ElButton: typeof import('element-plus/es')['ElButton']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElIconCircleClose: typeof import('@element-plus/icons-vue')['CircleClose']
ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
ElIconPlus: typeof import('@element-plus/icons-vue')['Plus']
ElImage: typeof import('element-plus/es')['ElImage']
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElMain: typeof import('element-plus/es')['ElMain']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElText: typeof import('element-plus/es')['ElText']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTransfer: typeof import('element-plus/es')['ElTransfer']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
export interface GlobalDirectives {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}
// For TSX support
declare global {
const ElAside: typeof import('element-plus/es')['ElAside']
const ElAvatar: typeof import('element-plus/es')['ElAvatar']
const ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
const ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
const ElButton: typeof import('element-plus/es')['ElButton']
const ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
const ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
const ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
const ElContainer: typeof import('element-plus/es')['ElContainer']
const ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
const ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
const ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
const ElDialog: typeof import('element-plus/es')['ElDialog']
const ElDivider: typeof import('element-plus/es')['ElDivider']
const ElDropdown: typeof import('element-plus/es')['ElDropdown']
const ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
const ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
const ElEmpty: typeof import('element-plus/es')['ElEmpty']
const ElForm: typeof import('element-plus/es')['ElForm']
const ElFormItem: typeof import('element-plus/es')['ElFormItem']
const ElHeader: typeof import('element-plus/es')['ElHeader']
const ElIcon: typeof import('element-plus/es')['ElIcon']
const ElIconCircleClose: typeof import('@element-plus/icons-vue')['CircleClose']
const ElIconPicture: typeof import('@element-plus/icons-vue')['Picture']
const ElIconPlus: typeof import('@element-plus/icons-vue')['Plus']
const ElImage: typeof import('element-plus/es')['ElImage']
const ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
const ElInput: typeof import('element-plus/es')['ElInput']
const ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
const ElMain: typeof import('element-plus/es')['ElMain']
const ElOption: typeof import('element-plus/es')['ElOption']
const ElPagination: typeof import('element-plus/es')['ElPagination']
const ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
const ElRadio: typeof import('element-plus/es')['ElRadio']
const ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
const ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
const ElSelect: typeof import('element-plus/es')['ElSelect']
const ElSwitch: typeof import('element-plus/es')['ElSwitch']
const ElTable: typeof import('element-plus/es')['ElTable']
const ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
const ElTabPane: typeof import('element-plus/es')['ElTabPane']
const ElTabs: typeof import('element-plus/es')['ElTabs']
const ElTag: typeof import('element-plus/es')['ElTag']
const ElText: typeof import('element-plus/es')['ElText']
const ElTooltip: typeof import('element-plus/es')['ElTooltip']
const ElTransfer: typeof import('element-plus/es')['ElTransfer']
const ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
const ElUpload: typeof import('element-plus/es')['ElUpload']
const RouterLink: typeof import('vue-router')['RouterLink']
const RouterView: typeof import('vue-router')['RouterView']
}

View File

@ -3,8 +3,21 @@
ref="formPage"
:action-column="actionColumn"
:left-tools="leftTools"
:paging="paging">
:paging="paging"
:tableProps="tableProps">
<template #searchFormItem="{searchForm}">
<ElFormItem label="账号">
<ElInput v-model="searchForm.username" placeholder="账号"/>
</ElFormItem>
<ElFormItem label="客户姓名">
<ElInput v-model="searchForm.nickname" placeholder="客户姓名"/>
</ElFormItem>
<ElFormItem label="联系电话">
<ElInput v-model="searchForm.phone" placeholder="联系电话"/>
</ElFormItem>
<ElFormItem label="企业名称">
<ElInput v-model="searchForm.orgName" placeholder="企业名称"/>
</ElFormItem>
<ElFormItem label="身份类型">
<ElSelect v-model="searchForm.identityCategory" placeholder="身份类型">
<ElOption v-for="item in identityCategory" :key="item.val" :label="item.txt" :value="item.val"/>
@ -15,43 +28,66 @@
<ElOption v-for="item in settlementWay" :key="item.val" :label="item.txt" :value="item.val"/>
</ElSelect>
</ElFormItem>
<ElFormItem label="账号">
<ElInput v-model="searchForm.username" placeholder="账号"/>
</ElFormItem>
<ElFormItem label="姓名">
<ElInput v-model="searchForm.nickname" placeholder="姓名"/>
</ElFormItem>
<ElFormItem label="企业名称">
<ElInput v-model="searchForm.orgId" placeholder="企业名称"/>
</ElFormItem>
<ElFormItem label="联系电话">
<ElInput v-model="searchForm.phone" placeholder="联系电话"/>
<ElFormItem label="注册时间">
<ADtPicker v-model="searchForm.regdateTimes" :change-handler="research"/>
</ElFormItem>
</template>
<template #simpleSearchFormItem="{searchForm}">
<ElFormItem>
<ElInput v-model="searchForm.orgId" placeholder="企业名称"/>
</ElFormItem>
<ElFormItem>
<ElInput v-model="searchForm.nickname" placeholder="姓名"/>
<ElInput v-model="searchForm.nickname" placeholder="客户姓名"/>
</ElFormItem>
<ElFormItem>
<ElInput v-model="searchForm.phone" placeholder="联系电话"/>
</ElFormItem>
<ElFormItem>
<ElInput v-model="searchForm.orgName" placeholder="企业名称"/>
</ElFormItem>
</template>
<template #columns>
<ElTableColumn label="账号" prop="username"/>
<ElTableColumn label="联系人" prop="nickname"/>
<ElTableColumn label="身份类型" prop="identityCategoryTxt"/>
<ElTableColumn label="企业信息" prop="orgId"/>
<ElTableColumn label="客户姓名" prop="customerName"/>
<ElTableColumn label="结算方式" prop="settlementWayTxt"/>
<ElTableColumn label="是否管理员">
<ElTableColumn label="客户姓名" prop="nickname"/>
<ElTableColumn label="联系电话" prop="phone">
<template #default="scope">
{{ scope.row.manager ? '是' : '否' }}
<span>
<AIcon name="dianhua-1" style="color: var(--el-color-danger); font-weight: 600"/>
<span style="margin-left: 8px">{{ scope.row.phone }}</span>
</span>
</template>
</ElTableColumn>
<ElTableColumn label="身份类型">
<template #default="scope">
<span>
<AIcon v-if="scope.row.identityCategory === identityCategory.ChanFei" name="kehu" style="color: var(--main-color); font-weight: 600"/>
<AIcon v-else-if="scope.row.identityCategory === identityCategory.YunShu" name="yunshu" style="color: var(--main-color); font-weight: 600"/>
<AIcon v-else-if="scope.row.identityCategory === identityCategory.XiaoNa" name="xiaonachang" style="color: var(--main-color); font-weight: 600"/>
<AIcon v-else-if="scope.row.identityCategory === identityCategory.CaiGou" name="icon-cart" style="color: var(--main-color); font-weight: 600"/>
<AIcon v-else-if="scope.row.identityCategory === identityCategory.SiJi" name="siji" style="color: var(--main-color); font-weight: 600"/>
<span style="margin-left: 8px">{{ scope.row.identityCategoryTxt }}</span>
</span>
</template>
</ElTableColumn>
<ElTableColumn label="企业名称" prop="orgName">
<template #default="scope">
<span>{{ scope.row.orgName ?? '-' }}</span>
</template>
</ElTableColumn>
<ElTableColumn label="结算方式" prop="">
<template #default="scope">
<span>
<AIcon v-if="scope.row.settlementWay === settlementWay.YueJie" name="yuejie" style="color: var(--el-color-success); font-weight: 600"/>
<AIcon v-else-if="scope.row.settlementWay === settlementWay.YuE" name="yue" style="color: var(--el-color-success); font-weight: 600"/>
<AIcon v-else-if="scope.row.settlementWay === settlementWay.XianFu" name="weixin" style="color: var(--el-color-success); font-weight: 600"/>
<span style="margin-left: 8px">{{ scope.row.settlementWayTxt }}</span>
</span>
</template>
</ElTableColumn>
<ElTableColumn label="企业负责人">
<template #default="scope">
<ElTag v-if="scope.row.manager" type="success"></ElTag>
<ElTag v-else type="danger"></ElTag>
</template>
</ElTableColumn>
<ElTableColumn label="联系电话" prop="phone"/>
<ElTableColumn label="注册时间" prop="regdate"/>
</template>
<CustomerForm ref="customerForm" :research="research"/>
@ -71,58 +107,25 @@ import {
identityCategory,
settlementWay,
} from '@/pages/cst/customer/constants.ts'
import ADtPicker from '@/components/a-dt-picker/ADtPicker.vue'
import AIcon from '@/components/a-icon/AIcon.vue'
import type { TableProps } from 'element-plus'
import { CustomerTypes } from '@/pages/cst/customer/customer'
const payList = [
{
value: 'YueJie',
label: '月结',
},
{
value: 'YuE',
label: '余额',
},
{
value: 'XianFu',
label: '现付',
},
]
const bizList = [
{
value: 'ChanFei',
label: '产废方',
},
{
value: 'YunShu',
label: '运输方',
},
{
value: 'XiaoNa',
label: '消纳方',
},
{
value: 'CaiGou',
label: '采购方',
},
{
value: 'SiJi',
label: '司机',
},
]
const customerFormIns = useTemplateRef<InstanceType<typeof CustomerForm>>('customerForm')
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')
const leftTools: ToolType[] = [
{
icon: 'Plus',
label: '新建',
action() {
customerFormIns.value?.open()
},
},
/* {
icon: 'Plus',
label: '新建',
action() {
customerFormIns.value?.open()
},
} ,*/
]
const actionColumn = reactive<ActionColumnType<CustomerTypes.SearchCustomerResult>>({
const actionColumn = reactive<ActionColumnType<CustomerTypes.TableData>>({
tableActions: [
{
tooltip: '编辑',
@ -131,7 +134,7 @@ const actionColumn = reactive<ActionColumnType<CustomerTypes.SearchCustomerResul
customerFormIns.value?.open(row)
},
},
{
/* {
icon: 'Delete',
loading: false,
type: 'danger',
@ -146,9 +149,23 @@ const actionColumn = reactive<ActionColumnType<CustomerTypes.SearchCustomerResul
return true
})
},
},
}, */
],
})
const tableProps = {
spanMethod({row, column}) {
if ([ 'username', 'nickname', 'phone', 'regdate' ].includes(column.prop!)) {
return {
rowspan: 1,
colspan: 1,
}
}
return {
rowspan: row.rowCount,
colspan: 1,
}
},
} as Pick<TableProps<CustomerTypes.TableData>, 'spanMethod'>
function research() {
formPageIns.value?.doSearch()
@ -156,8 +173,22 @@ function research() {
function paging(param: CustomerTypes.SearchCustomerParam) {
return CustomerApi.paging(param)
.then(res => {
const dataList: CustomerTypes.TableData[] = []
for (const {userId, username, nickname, phone, customerInfos} of res.data) {
for (let i = 0; i < customerInfos.length; i++) {
const it = customerInfos[i]
dataList.push({
...it,
rowCount: i === 0 ? customerInfos.length : 0,
userId,
username,
nickname,
phone,
})
}
}
return dataList
})
}
</script>

View File

@ -4,20 +4,26 @@
:details-loader="detailsLoader"
:do-submit="doSubmit"
:rules="rules"
:title="status === 'add' ? '新建客户' : '修改客户'">
:title="status === 'add' ? '新建客户' : '修改客户信息'">
<template #default="{formData}">
<div class="form-items">
<ElFormItem label="身份类型" prop="identityCategory">
<ElSelect v-model="formData.identityCategory" placeholder="身份类型">
<ElOption v-for="item in identityCategory" :key="item.val" :label="item.txt" :value="item.val"/>
</ElSelect>
<ElFormItem label="账号" prop="username">
<ElInput :model-value="formData.username" disabled placeholder="账号"/>
</ElFormItem>
<ElFormItem label="客户姓名" prop="customerName">
<ElInput v-model="formData.customerName" placeholder="客户姓名"/>
<ElFormItem label="客户姓名" prop="nickname">
<ElInput v-model="formData.nickname" placeholder="客户姓名"/>
</ElFormItem>
<ElFormItem label="所属企业" prop="orgName">
<ElInput :model-value="formData.orgName ?? '-' " disabled placeholder="所属企业"/>
</ElFormItem>
<ElFormItem label="联系电话" prop="phone">
<ElInput v-model="formData.phone" placeholder="联系电话"/>
</ElFormItem>
<ElFormItem label="身份类型" prop="identityCategory">
<ElSelect :model-value="formData.identityCategory" disabled placeholder="身份类型">
<ElOption v-for="item in identityCategory" :key="item.val" :label="item.txt" :value="item.val"/>
</ElSelect>
</ElFormItem>
<ElFormItem label="结算方式" prop="settlementWay">
<ElSelect v-model="formData.settlementWay" placeholder="结算方式">
<ElOption v-for="item in settlementWay" :key="item.val" :label="item.txt" :value="item.val"/>
@ -39,7 +45,6 @@ import {
} from '@/pages/cst/customer/constants.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const props = withDefaults(defineProps<{
research?: () => void
}>(), {
@ -48,20 +53,10 @@ const props = withDefaults(defineProps<{
})
const formPanelIns = useTemplateRef<ComponentExposed<typeof AFormPanel>>('formPanel')
const status = ref<'add' | 'modify'>('add')
const rules = reactive<FormRules<CustomerTypes.SearchCustomerResult>>({
id: [ {required: true, message: '请填写Id', trigger: 'blur'} ],
userId: [ {required: true, message: '请填写用户', trigger: 'blur'} ],
identityCategory: [ {required: true, message: '请填写身份类型', trigger: 'blur'} ],
orgId: [ {required: true, message: '请填写企业信息', trigger: 'blur'} ],
customerName: [ {required: true, message: '请填写客户姓名', trigger: 'blur'} ],
phone: [ {required: true, message: '请填写客户联系电话', trigger: 'blur'} ],
settlementWay: [ {required: true, message: '请填写结算方式', trigger: 'blur'} ],
manager: [ {required: true, message: '请填写是否管理员', trigger: 'blur'} ],
creatorId: [ {required: true, message: '请填写创建人', trigger: 'blur'} ],
modifierId: [ {required: true, message: '请填写修改人', trigger: 'blur'} ],
createTime: [ {required: true, message: '请填写创建时间', trigger: 'blur'} ],
modifyTime: [ {required: true, message: '请填写修改时间', trigger: 'blur'} ],
deleted: [ {required: true, message: '请填写是否删除', trigger: 'blur'} ],
const rules = reactive<FormRules<CustomerTypes.TableData>>({
nickname: [ {required: true, message: '请填写客户姓名', trigger: 'blur'} ],
phone: [ {required: true, message: '请填写联系电话', trigger: 'blur'} ],
settlementWay: [ {required: true, message: '请选择结算方式', trigger: 'blur'} ],
})
function detailsLoader(id?: string) {
@ -77,7 +72,7 @@ function detailsLoader(id?: string) {
}
}
function doSubmit(data: CustomerTypes.SearchCustomerResult) {
function doSubmit(data: CustomerTypes.TableData) {
if (status.value === 'add') {
return CustomerApi.add(data)
.then(props.research)
@ -87,9 +82,8 @@ function doSubmit(data: CustomerTypes.SearchCustomerResult) {
}
}
defineExpose({
open(data?: CustomerTypes.SearchCustomerResult) {
open(data?: CustomerTypes.TableData) {
formPanelIns.value?.open(data?.id)
},
})
@ -97,7 +91,7 @@ defineExpose({
<style lang="stylus" scoped>
.form-items {
grid-template-columns: 1fr;
grid-template-columns: 1fr 1fr;
}
</style>

View File

@ -3,61 +3,59 @@ export {}
declare global {
namespace CustomerTypes {
interface SearchCustomerParam extends G.PageParam {
// Id
id?: string
// 用户 Id一个用户可以有多个身份
userId?: string
username: string
// 客户姓名
nickname?: string
// 客户联系电话
phone?: string
orgName?: string
// 身份类型多个身份多条数据PingTai-->平台、ChanFei-->产废方、QingYun-->清运方、XiaoNa-->消纳方、CaiGou-->采购方
identityCategory?: string
// 企业信息 Idcst_org.id
orgId?: string
// 结算方式YueJie-->月结、YuE-->余额、XianFu-->现付
settlementWay?: string
regdateTimes: [ string | undefined, string | undefined ]
regdateStart?: string
regdateEnd?: string
}
interface CustomerInfo {
// Id
id?: string
// 客户姓名
customerName?: string
// 客户联系电话
phone?: string
// 身份类型多个身份多条数据PingTai-->平台、ChanFei-->产废方、QingYun-->清运方、XiaoNa-->消纳方、CaiGou-->采购方
identityCategory?: string
identityCategoryTxt?: string
// 企业信息 Idcst_org.id
orgId?: string
orgName?: string
// 结算方式YueJie-->月结、YuE-->余额、XianFu-->现付
settlementWay?: string
settlementWayTxt?: string
// 是否管理员是否为当前的企业管理员0-->否、1-->是
manager?: boolean
// 创建人 Idsys_user.id
creatorId?: string
// 修改人 Idsys_user.id
modifierId?: string
// 创建时间
createTime?: string
// 修改时间
modifyTime?: string
// 是否删除0-->未删除、1-->已删除
deleted?: boolean
}
interface SearchCustomerResult {
// Id
id?: string
// 用户 Id一个用户可以有多个身份
userId?: string
// 身份类型多个身份多条数据PingTai-->平台、ChanFei-->产废方、QingYun-->清运方、XiaoNa-->消纳方、CaiGou-->采购方
identityCategory?: string
// 企业信息 Idcst_org.id
orgId?: string
username?: string
// 客户姓名
customerName?: string
nickname?: string
// 客户联系电话
phone?: string
// 结算方式YueJie-->月结、YuE-->余额、XianFu-->现付
settlementWay?: string
// 是否管理员是否为当前的企业管理员0-->否、1-->是
manager?: boolean
// 创建人 Idsys_user.id
creatorId?: string
// 修改人 Idsys_user.id
modifierId?: string
// 创建时间
createTime?: string
// 修改时间
modifyTime?: string
// 是否删除0-->未删除、1-->已删除
deleted?: boolean
customerInfos?: CustomerInfo[]
}
interface TableData extends CustomerInfo {
rowCount: number
userId?: string
username?: string
// 客户姓名
nickname?: string
phone?: string
}
interface AddCustomerParam {

View File

@ -6,10 +6,13 @@
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"jsx": "preserve",
"jsxImportSource": "vue",
/*"erasableSyntaxOnly": false,
"noUncheckedSideEffectImports": true,
"allowSyntheticDefaultImports": true,*/
"baseUrl": ".",
"paths": {
"@/*": [