master
lzq 2026-01-22 16:02:05 +08:00
parent 6ac094725e
commit 0890fb8716
30 changed files with 463 additions and 356 deletions

View File

@ -0,0 +1,30 @@
export interface EnumItem {
val: string
txt: string
}
export type EnhancedEnum<T> = T & {
// @ts-ignore
[key in T[number]['val']]: T[number]['val']
} & {
// @ts-ignore
[key in `${T[number]['val']}Txt`]: T[number]['txt']
} & {
// @ts-ignore
of: (val: string) => T[number] | undefined
// @ts-ignore
txt: (val: T[number]['val']) => T[number]['txt']
}
export function createEnum<T>(enums: T): EnhancedEnum<T> {
const e = enums as EnhancedEnum<T>
for (let enumItem of enums as EnumItem[]) {
// @ts-ignore
e[enumItem.val] = enumItem.val
// @ts-ignore
e[enumItem.val + 'Txt'] = enumItem.txt
}
// @ts-ignore
e.of = (val: string) => ((enums as EnumItem[]).find((item) => item.val === val))
return e
}

View File

@ -45,6 +45,7 @@ const showDialog = computed({
},
})
const submiting = ref(false)
const enableRender = ref(false)
let moveHandle = useMove(id)
function openedHandler() {
@ -68,6 +69,9 @@ function closedHandler() {
.setTriggerArea()
}
onMounted(() => {
enableRender.value = true
})
onActivated(() => {
moveHandle.enable()
})
@ -79,6 +83,7 @@ onUnmounted(() => {
<template>
<ElDialog
v-if="enableRender"
:close-on-click-modal="false"
:modal="false"
:modal-class="modalClass"
@ -86,6 +91,7 @@ onUnmounted(() => {
:title="title"
class="draggable-dialog"
destroy-on-close
append-to="#dialog-anchor"
:width="width" @close="closed"
@closed="closedHandler"
@opened="openedHandler"

View File

@ -3,7 +3,7 @@ import Utils from '@/common/utils'
import { elIcons } from '@/common/element/element.ts'
const props = withDefaults(defineProps<{
modelValue?: string | string[],
modelValue?: string | string[] | null,
multiple?: boolean,
placeholder?: string,
displayField: string,

View File

@ -0,0 +1,84 @@
<script generic="T extends object" lang="ts" setup>
import ADialog from '@/components/a-dialog/ADialog.vue'
import Utils from '@/common/utils'
import type { Arrayable } from 'element-plus/es/utils'
import {
ElMessage,
type FormInstance,
type FormItemRule,
} from 'element-plus'
import FormUtil from '@/common/utils/formUtil.ts'
const props = withDefaults(
defineProps<{
title: string
detailsLoader: (id?: string) => Promise<T | undefined | null | void>
doSubmit: (data: T) => Promise<boolean | void>
rules?: Partial<Record<string, Arrayable<FormItemRule>>>
labelWidth?: string
}>(),
{
rules: () => ({} as Partial<Record<string, Arrayable<FormItemRule>>>),
labelWidth: '80px',
})
const formIns = useTemplateRef<FormInstance>('formRef')
const showDialog = ref(false)
const loading = ref(false)
const formData = Utils.resetAble(reactive<T>({} as T))
function dialogCloseHandler() {
formData.$reset()
}
function submitHandler() {
return FormUtil.submit(formIns, () => props.doSubmit(formData.$clone() as T))
.then(res => {
ElMessage.success('提交成功')
if ((res ?? true)) {
showDialog.value = false
}
})
}
defineExpose({
open(id?: string) {
loading.value = true
props.detailsLoader(id)
.then(res => {
formData.$reset((res ?? {}) as any)
})
.finally(() => {
loading.value = false
})
showDialog.value = true
},
})
</script>
<template>
<ADialog
v-model:show="showDialog"
:closed="dialogCloseHandler"
:submit-handler="submitHandler"
:title="title"
>
<ElForm
ref="formRef"
v-loading="loading"
:label-width="labelWidth" :model="formData"
:rules="rules"
class="form-panel">
<slot :formData="formData as T"/>
</ElForm>
</ADialog>
</template>
<style lang="stylus">
.form-panel > div:first-child {
padding 20px
display: grid;
gap: 0 30px;
}
</style>

View File

@ -1,8 +1,5 @@
<script generic="F extends object,TT extends DefaultRow" lang="ts" setup>
import {
elIcons,
type ElIconType,
} from '@/common/element/element.ts'
import { elIcons } from '@/common/element/element.ts'
import Page from '@/components/page/Page.vue'
import Utils, { type ResetAble } from '@/common/utils'
import Colls from '@/common/utils/colls.ts'
@ -11,44 +8,14 @@ import type { R } from '@/common/utils/http-util.ts'
import type {
TableColumnCtx,
TableInstance,
TableProps,
} from 'element-plus'
import type { DefaultRow } from 'element-plus/es/components/table/src/table/defaults'
import type { FormProps } from 'element-plus/es/components/form/src/form'
export interface ToolType {
icon?: ElIconType
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
label?: string
action: () => void
}
export interface TableActionType<T> {
icon?: ElIconType
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
label?: string | ((data: { row: T, column: TableColumnCtx, $index: number }) => string)
tooltip?: string | ((data: { row: T, column: TableColumnCtx, $index: number }) => string)
loading?: boolean
textBtn?: boolean
show?: (data: { row: T, column: TableColumnCtx, $index: number }) => boolean
action: (data: { row: T, column: TableColumnCtx, $index: number }) => Promise<boolean> | void
confirm?: {
title: string | ((data: { row: T, column: TableColumnCtx, $index: number }) => string)
width?: string
confirmButtonText?: string
cancelButtonText?: string
}
}
export interface ActionColumnType<T> {
width?: string
tableActions: TableActionType<T>[]
}
export type TablePropsType<T extends DefaultRow, F extends object> = Omit<TableProps<T>, 'data' | 'headerRowClassName' | 'cellClassName' | 'context'> & {
treeLoad?: (param: F, row: T, expanded: any, resolve?: (data: T[]) => void) => void
}
export type FormPropsType = Partial<FormProps>
import type {
ActionColumnType,
FormPropsType,
TablePropsType,
ToolType,
} from '@/components/page/a-page-type.ts'
const props = withDefaults(
defineProps<{
@ -202,7 +169,7 @@ onMounted(doSearch)
<button style="display: none" type="submit"></button>
</ElForm>
<ElTooltip content="刷新" placement="top">
<ElDropdown split-button @click="doSearch" @command="(command)=>{
<ElDropdown split-button @click="doSearch" @command="(command: string)=>{
if(command === 'reset'){
doReset()
}
@ -210,7 +177,7 @@ onMounted(doSearch)
<ElButton :icon="elIcons.Refresh" :loading="loading" type="default"/>
<template #dropdown>
<ElDropdownMenu slot="dropdown">
<ElDropdownItem command="reset">重置并刷新</ElDropdownItem>
<ElDropdownItem :icon="elIcons.Search" command="reset">重置并刷新</ElDropdownItem>
</ElDropdownMenu>
</template>
</ElDropdown>

View File

@ -3,7 +3,7 @@
</script>
<template>
<div class="page-wrapper">
<div id="dialog-anchor" class="page-wrapper">
<slot/>
</div>
</template>

View File

@ -0,0 +1,41 @@
import type { ElIconType } from '@/common/element/element.ts'
import type {
TableColumnCtx,
TableProps,
} from 'element-plus'
import type { DefaultRow } from 'element-plus/es/components/table/src/table/defaults'
import type { FormProps } from 'element-plus/es/components/form/src/form'
export interface ToolType {
icon?: ElIconType
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
label?: string
action: () => void
}
export interface TableActionType<T> {
icon?: ElIconType
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
label?: string | ((data: { row: T, column: TableColumnCtx, $index: number }) => string)
tooltip?: string | ((data: { row: T, column: TableColumnCtx, $index: number }) => string)
loading?: boolean
textBtn?: boolean
show?: (data: { row: T, column: TableColumnCtx, $index: number }) => boolean
action: (data: { row: T, column: TableColumnCtx, $index: number }) => Promise<boolean> | void
confirm?: {
title: string | ((data: { row: T, column: TableColumnCtx, $index: number }) => string)
width?: string
confirmButtonText?: string
cancelButtonText?: string
}
}
export interface ActionColumnType<T> {
width?: string
tableActions: TableActionType<T>[]
}
export type TablePropsType<T extends DefaultRow, F extends object> = Omit<TableProps<T>, 'data' | 'headerRowClassName' | 'cellClassName' | 'context'> & {
treeLoad?: (param: F, row: T, expanded: any, resolve?: (data: T[]) => void) => void
}
export type FormPropsType = Partial<FormProps>

View File

@ -5,6 +5,7 @@
// ------
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
import { GlobalComponents } from 'vue'
export {}

View File

@ -38,10 +38,11 @@
<script lang="ts" setup>
import CustomerApi from '@/pages/cst/customer/customer-api.ts'
import CustomerForm from '@/pages/cst/customer/CustomerForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const payList = [

View File

@ -76,10 +76,11 @@
<script lang="ts" setup>
import StationApi from '@/pages/cst/station/station-api.ts'
import StationForm from '@/pages/cst/station/StationForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const stationFormIns = useTemplateRef<InstanceType<typeof StationForm>>('stationForm')

View File

@ -8,7 +8,7 @@
<template #searchFormItem="{ searchForm }">
<ElFormItem label="业务类型">
<ElSelect v-model="searchForm.bizType" clearable placeholder="业务类型" @change="research">
<ElOption v-for="item in bizList" :key="item.value" :label="item.label" :value="item.value"/>
<ElOption v-for="item in bizType" :key="item.val" :label="item.txt" :value="item.val"/>
</ElSelect>
</ElFormItem>
<ElFormItem label="分类名称">
@ -21,7 +21,7 @@
<template #simpleSearchFormItem="{ searchForm }">
<ElFormItem style="min-width: 200px">
<ElSelect v-model="searchForm.bizType" clearable placeholder="业务类型" @change="research">
<ElOption v-for="item in bizList" :key="item.value" :label="item.label" :value="item.value"/>
<ElOption v-for="item in bizType" :key="item.val" :label="item.txt" :value="item.val"/>
</ElSelect>
</ElFormItem>
<ElFormItem>
@ -38,7 +38,7 @@
<ElTableColumn label="分类名称" prop="categoryName"/>
<ElTableColumn label="创建时间" prop="createTime"/>
</template>
<GoodsCategoryForm ref="goodsCategoryForm" @edit-succ="research"/>
<GoodsCategoryForm ref="goodsCategoryForm" :research="research"/>
</FormPage>
</template>
@ -47,28 +47,16 @@ import type { ComponentExposed } from 'vue-component-type-helpers'
import GoodsCategoryApi from '@/pages/gds/goods-category/goods-category-api.ts'
import GoodsCategoryForm from '@/pages/gds/goods-category/GoodsCategoryForm.vue'
import AppApi from '@/common/app/app-api.ts'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import ADtPicker from '@/components/a-dt-picker/ADtPicker.vue'
import { bizType } from '@/pages/gds/goods-category/constants.ts'
const goodsCategoryFormIns = useTemplateRef<InstanceType<typeof GoodsCategoryForm>>('goodsCategoryForm')
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')
const bizList = [
{
value: 'ZaiShengPin',
label: '再生品',
},
{
value: 'HuiShouPin',
label: '回收品',
},
{
value: 'QiTa',
label: '其他',
},
]
const leftTools: ToolType[] = [
{

View File

@ -0,0 +1,39 @@
<script lang="ts" setup>
import ADropTable from '@/components/a-drop-table/ADropTable.vue'
import GoodsCategoryApi from '@/pages/gds/goods-category/goods-category-api.ts'
const dropTableColumns = [
{
label: '业务类型',
prop: 'bizTypeTxt',
},
{
label: '分类名称',
prop: 'categoryName',
},
]
const dropTableLoader = (param: GoodsCategoryTypes.SearchGoodsCategoryParam) => {
return GoodsCategoryApi.paging(param).then(res => res.data)
}
const props = defineProps<{
modelValue: string | undefined | null,
}>()
const emits = defineEmits<{
'update:modelValue': [ value: string | undefined | null ]
}>()
const goodsCategoryId = computed({
get: () => props.modelValue,
set: (val) => emits('update:modelValue', val),
})
</script>
<template>
<ADropTable v-model="goodsCategoryId"
:columns="dropTableColumns"
:loader="dropTableLoader"
display-field="categoryName"/>
</template>

View File

@ -1,68 +1,49 @@
<template>
<ADialog
v-model:show="showDialog"
:closed="dialogCloseHandler"
:submit-handler="submitHandler"
<AFormPanel
ref="formPanel"
:title="status === 'add' ? '新建产品分类' : '修改产品分类'"
:details-loader="detailsLoader"
:do-submit="doSubmit"
:rules="rules"
>
<ElForm ref="goodsCategoryForm" :model="formData" :rules="rules" class="form-panel" label-width="80px">
<ElFormItem label="图片" prop="picture">
<Uploader ref="uploader" v-model:file="formData.picture"/>
</ElFormItem>
<ElFormItem label="业务类型" prop="bizType">
<ElSelect v-model="formData.bizType" :disabled="status === 'view'" placeholder="业务类型">
<ElOption v-for="item in bizList" :key="item.value" :label="item.label" :value="item.value"/>
</ElSelect>
</ElFormItem>
<ElFormItem label="分类名称" prop="categoryName">
<ElInput v-model="formData.categoryName" :disabled="status === 'view'" placeholder="分类名称"/>
</ElFormItem>
<ElFormItem label="排序" prop="sort">
<ElInputNumber v-model="formData.sort" :disabled="status === 'view'" :min="0" placeholder="排序"/>
</ElFormItem>
</ElForm>
</ADialog>
<template #default="{formData}">
<div class="form-items">
<ElFormItem label="图片" prop="picture">
<Uploader ref="uploader" v-model:file="formData.picture"/>
</ElFormItem>
<ElFormItem label="业务类型" prop="bizType">
<ElSelect v-model="formData.bizType" :disabled="status === 'view'" placeholder="业务类型">
<ElOption v-for="item in bizType" :key="item.val" :label="item.txt" :value="item.val"/>
</ElSelect>
</ElFormItem>
<ElFormItem label="分类名称" prop="categoryName">
<ElInput v-model="formData.categoryName" :disabled="status === 'view'" placeholder="分类名称"/>
</ElFormItem>
<ElFormItem label="排序" prop="sort">
<ElInputNumber v-model="formData.sort" :disabled="status === 'view'" :min="0" placeholder="排序"/>
</ElFormItem>
</div>
</template>
</AFormPanel>
</template>
<script lang="ts" setup>
import GoodsCategoryApi from '@/pages/gds/goods-category/goods-category-api.ts'
import Strings from '@/common/utils/strings.ts'
import FormUtil from '@/common/utils/formUtil.ts'
import Uploader from '@/components/uploader/Uploader.vue'
import { type FormRules } from 'element-plus'
import AFormPanel from '@/components/a-form-panel/AFormPanel.vue'
import { bizType } from '@/pages/gds/goods-category/constants.ts'
import Utils from '@/common/utils'
import {
ElMessage,
type FormInstance,
type FormRules,
} from 'element-plus'
import ADialog from '@/components/a-dialog/ADialog.vue'
const emits = defineEmits([ 'editSucc' ])
const showDialog = ref(false)
const submiting = ref(false)
const status = ref<'add' | 'view' | 'modify'>('add')
const goodsCategoryFormIns = useTemplateRef<FormInstance>('goodsCategoryForm')
const props = withDefaults(defineProps<{
research?: () => void
}>(), {
research: () => {
},
})
const formPanelIns = useTemplateRef<InstanceType<typeof AFormPanel>>('formPanel')
const uploaderIns = useTemplateRef<InstanceType<typeof Uploader>>('uploader')
const bizList = [
{
value: 'ZaiShengPin',
label: '再生品',
},
{
value: 'HuiShouPin',
label: '回收品',
},
{
value: 'QiTa',
label: '其他',
},
]
const formData = Utils.resetAble(reactive<any>({}))
const status = ref<'add' | 'view' | 'modify'>('add')
const rules = reactive<FormRules<GoodsCategoryTypes.SearchGoodsCategoryResult>>({
bizType: [ {required: true, message: '请填写业务类型', trigger: 'blur'} ],
categoryName: [ {required: true, message: '请填写分类名称', trigger: 'blur'} ],
@ -70,59 +51,40 @@ const rules = reactive<FormRules<GoodsCategoryTypes.SearchGoodsCategoryResult>>(
sort: [ {required: true, message: '请填写排序', trigger: 'blur'} ],
})
function dialogCloseHandler() {
formData.$reset()
}
function submitHandler() {
if (status.value === 'view') return Promise.reject()
submiting.value = true
if (formData.id != null) {
return FormUtil.submit(goodsCategoryFormIns, () => GoodsCategoryApi.modify(formData))
.then(() => {
ElMessage.success('修改成功')
emits('editSucc')
showDialog.value = false
})
.finally(() => {
submiting.value = false
})
function detailsLoader(id?: string) {
if (Strings.isBlank(id)) {
status.value = 'add'
return Promise.resolve()
} else {
return FormUtil.submit(goodsCategoryFormIns, () => GoodsCategoryApi.add(formData))
.then(() => {
ElMessage.success('添加成功')
emits('editSucc')
showDialog.value = false
})
.finally(() => {
submiting.value = false
status.value = 'modify'
return GoodsCategoryApi.detail(id!)
.then((res) => {
if (res.data.picture != null) uploaderIns.value?.setDefaultFiles([ res.data.picture ])
return res.data
})
}
}
function doSubmit(data: GoodsCategoryTypes.SearchGoodsCategoryResult) {
if (status.value === 'add') {
return GoodsCategoryApi.add(data)
.then(props.research)
} else if (status.value === 'modify') {
return GoodsCategoryApi.modify(data)
.then(props.research)
}
}
defineExpose({
open(data: any = {}) {
showDialog.value = true
if (!Strings.isBlank(data.id)) {
status.value = 'modify'
GoodsCategoryApi.detail(data.id!).then((res) => {
formData.$reset(res.data)
if (res.data.picture != null) uploaderIns.value?.setDefaultFiles([ res.data.picture ])
})
} else {
status.value = 'add'
formData.$reset(data)
}
open(data?: GoodsCategoryTypes.SearchGoodsCategoryResult) {
formPanelIns.value?.open(data?.id)
},
})
</script>
<style lang="stylus" scoped>
.form-panel {
padding 20px
display: grid;
gap: 0 30px;
.form-items {
grid-template-columns: 1fr 1fr;
grid-template-areas: "picture bizType" \
"picture categoryName" \
"picture sort";

View File

@ -0,0 +1,18 @@
import { createEnum } from '@/common/utils/enums.ts'
const enums = [
{
val: 'ZaiShengPin',
txt: '再生品',
},
{
val: 'HuiShouPin',
txt: '回收品',
},
{
val: 'QiTa',
txt: '其他',
},
] as const
export const bizType = createEnum(enums)

View File

@ -7,7 +7,7 @@
:paging="paging">
<template #searchFormItem="{ searchForm }">
<ElFormItem label="产品分类">
<ADropTable v-model="searchForm.goodsCategoryId as string" :columns="dropTableColumns" :loader="dropTableLoader" display-field="categoryName"/>
<GoodsCategoryDropTable v-model="searchForm.goodsCategoryId"/>
</ElFormItem>
<ElFormItem label="产品编码">
<ElInput v-model="searchForm.sn" placeholder="产品编码"/>
@ -45,7 +45,7 @@
<ElTableColumn label="备注" prop="memo"/>
<ElTableColumn label="创建时间" prop="createTime" width="160"/>
</template>
<GoodsForm ref="goodsForm" @edit-succ="editSuccHandler"/>
<GoodsForm ref="goodsForm" :research="research"/>
</FormPage>
</template>
@ -53,36 +53,18 @@
import GoodsApi from '@/pages/gds/goods/goods-api.ts'
import GoodsForm from '@/pages/gds/goods/GoodsForm.vue'
import AppApi from '@/common/app/app-api.ts'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
import ADropTable from '@/components/a-drop-table/ADropTable.vue'
import GoodsCategoryApi from '@/pages/gds/goods-category/goods-category-api.ts'
import ADtPicker from '@/components/a-dt-picker/ADtPicker.vue'
import GoodsCategoryDropTable from '@/pages/gds/goods-category/GoodsCategoryDropTable.vue'
const goodsFormIns = useTemplateRef<InstanceType<typeof GoodsForm>>('goodsForm')
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')
function editSuccHandler() {
formPageIns.value?.doSearch()
}
const dropTableColumns = [
{
label: '业务类型',
prop: 'bizTypeTxt',
},
{
label: '分类名称',
prop: 'categoryName',
},
]
const dropTableLoader = (param: GoodsCategoryTypes.SearchGoodsCategoryParam) => {
return GoodsCategoryApi.paging(param).then(res => res.data)
}
const actionColumn = reactive<ActionColumnType<GoodsTypes.SearchGoodsResult>>({
tableActions: [
{
@ -109,7 +91,7 @@ const actionColumn = reactive<ActionColumnType<GoodsTypes.SearchGoodsResult>>({
},
},
],
})
} as ActionColumnType<GoodsTypes.SearchGoodsResult>)
const leftTools: ToolType[] = [
{
icon: 'Plus',
@ -136,7 +118,7 @@ function enableGoodsHandler(enable: boolean, id: string) {
GoodsApi.enable({enable, id})
.then(() => {
ElMessage.success(enable ? '启用成功' : '禁用成功')
editSuccHandler()
research()
})
}
</script>

View File

@ -1,72 +1,66 @@
<template>
<ADialog
v-model:show="showDialog"
:closed="dialogCloseHandler"
:submit-handler="submitHandler"
<AFormPanel
ref="formPanel"
:title="status === 'add' ? '新建产品' : '修改产品'"
:details-loader="detailsLoader"
:do-submit="doSubmit"
:rules="rules"
>
<ElForm ref="goodsForm" :model="formData" :rules="rules" class="form-panel" label-width="80px">
<ElFormItem label="图片" prop="picture">
<Uploader
ref="uploader"
v-model:file="formData.picture"
:upload-props="{
accept: 'image/*',
listType:'picture-card'
}"/>
</ElFormItem>
<ElFormItem v-if="status !== 'add'" label="产品编码" prop="sn">
<ElInput v-model="formData.sn" placeholder="产品编码" readonly/>
</ElFormItem>
<ElFormItem label="产品分类" prop="goodsCategoryId">
<ADropTable v-model="formData.goodsCategoryId as string" :columns="dropTableColumns" :loader="dropTableLoader" display-field="categoryName"/>
</ElFormItem>
<ElFormItem label="产品名称" prop="goodsName">
<ElInput v-model="formData.goodsName" :disabled="status === 'view'" placeholder="产品名称"/>
</ElFormItem>
<ElFormItem label="规格" prop="specParams">
<ElInput v-model="formData.specParams" :disabled="status === 'view'" placeholder="规格"/>
</ElFormItem>
<ElFormItem label="排序" prop="sort">
<ElInputNumber v-model="formData.sort" :disabled="status === 'view'" placeholder="请输入排序"/>
</ElFormItem>
<ElFormItem label="计量单位" prop="unit">
<ADict v-model="formData.unit" :disabled="status === 'view'" dict-key="unit" placeholder="计量单位"/>
</ElFormItem>
<ElFormItem label="是否可用" prop="canuse">
<el-switch v-model="formData.canuse" :disabled="status === 'view'"/>
</ElFormItem>
<ElFormItem label="备注" prop="memo">
<ElInput v-model="formData.memo" :disabled="status === 'view'" placeholder="请输入备注"/>
</ElFormItem>
</ElForm>
</ADialog>
<template #default="{formData}">
<div class="form-items">
<ElFormItem label="图片" prop="picture">
<Uploader
ref="uploader"
v-model:file="formData.picture"/>
</ElFormItem>
<ElFormItem v-if="status !== 'add'" label="产品编码" prop="sn">
<ElInput v-model="formData.sn" placeholder="产品编码" readonly/>
</ElFormItem>
<ElFormItem label="产品分类" prop="goodsCategoryId">
<GoodsCategoryDropTable v-model="formData.goodsCategoryId"/>
</ElFormItem>
<ElFormItem label="产品名称" prop="goodsName">
<ElInput v-model="formData.goodsName" :disabled="status === 'view'" placeholder="产品名称"/>
</ElFormItem>
<ElFormItem label="规格" prop="specParams">
<ElInput v-model="formData.specParams" :disabled="status === 'view'" placeholder="规格"/>
</ElFormItem>
<ElFormItem label="排序" prop="sort">
<ElInputNumber v-model="formData.sort" :disabled="status === 'view'" placeholder="请输入排序"/>
</ElFormItem>
<ElFormItem label="计量单位" prop="unit">
<ADict v-model="formData.unit" :disabled="status === 'view'" dict-key="unit" placeholder="计量单位"/>
</ElFormItem>
<ElFormItem label="是否可用" prop="canuse">
<el-switch v-model="formData.canuse" :disabled="status === 'view'"/>
</ElFormItem>
<ElFormItem label="备注" prop="memo">
<ElInput v-model="formData.memo" :disabled="status === 'view'" placeholder="请输入备注"/>
</ElFormItem>
</div>
</template>
</AFormPanel>
</template>
<script lang="ts" setup>
import GoodsApi from '@/pages/gds/goods/goods-api.ts'
import Strings from '@/common/utils/strings.ts'
import FormUtil from '@/common/utils/formUtil.ts'
import Utils from '@/common/utils'
import {
ElMessage,
type FormInstance,
type FormRules,
} from 'element-plus'
import { type FormRules } from 'element-plus'
import Uploader from '@/components/uploader/Uploader.vue'
import GoodsCategoryApi from '@/pages/gds/goods-category/goods-category-api.ts'
import ADict from '@/components/a-dict/ADict.vue'
import ADialog from '@/components/a-dialog/ADialog.vue'
import ADropTable from '@/components/a-drop-table/ADropTable.vue'
import AFormPanel from '@/components/a-form-panel/AFormPanel.vue'
import GoodsCategoryDropTable from '@/pages/gds/goods-category/GoodsCategoryDropTable.vue'
const props = withDefaults(defineProps<{
research?: () => void
}>(), {
research: () => {
},
})
const emits = defineEmits([ 'editSucc' ])
const showDialog = ref(false)
const status = ref<'add' | 'view' | 'modify'>('add')
const goodsFormIns = useTemplateRef<FormInstance>('goodsForm')
const formPanelIns = useTemplateRef<InstanceType<typeof AFormPanel>>('formPanel')
const uploaderIns = useTemplateRef<InstanceType<typeof Uploader>>('uploader')
const formData = Utils.resetAble(reactive<GoodsTypes.SearchGoodsResult>({canuse: true}))
const status = ref<'add' | 'view' | 'modify'>('add')
const rules = reactive<FormRules<GoodsTypes.SearchGoodsResult>>({
goodsCategoryId: [ {required: true, message: '请填写产品类型', trigger: 'blur'} ],
sn: [ {required: true, message: '请填写产品编码', trigger: 'blur'} ],
@ -76,69 +70,48 @@ const rules = reactive<FormRules<GoodsTypes.SearchGoodsResult>>({
unit: [ {required: true, message: '请填写计量单位', trigger: 'blur'} ],
sort: [ {required: true, message: '请填写排序', trigger: 'blur'} ],
})
const dropTableColumns = [
{
label: '业务类型',
prop: 'bizTypeTxt',
},
{
label: '分类名称',
prop: 'categoryName',
},
]
const dropTableLoader = (param: GoodsCategoryTypes.SearchGoodsCategoryParam) => {
return GoodsCategoryApi.paging(param).then(res => res.data)
}
function dialogCloseHandler() {
formData.$reset()
}
function submitHandler() {
if (status.value === 'view') return Promise.reject()
if (formData.id != null) {
return FormUtil.submit(goodsFormIns, () => GoodsApi.modify(formData))
.then(() => {
ElMessage.success('修改成功')
emits('editSucc')
})
function detailsLoader(id?: string) {
if (Strings.isBlank(id)) {
status.value = 'add'
return Promise.resolve()
} else {
return FormUtil.submit(goodsFormIns, () => GoodsApi.add(formData))
.then(() => {
ElMessage.success('添加成功')
emits('editSucc')
status.value = 'modify'
return GoodsApi
.detail(id!)
.then((res) => {
if (res.data.picture != null) uploaderIns.value?.setDefaultFiles([ res.data.picture ])
return res.data
})
}
}
function doSubmit(data: GoodsTypes.SearchGoodsResult) {
if (status.value === 'add') {
return GoodsApi.add(data)
.then(props.research)
} else if (status.value === 'modify') {
return GoodsApi.modify(data)
.then(props.research)
}
}
defineExpose({
open(data: GoodsTypes.SearchGoodsResult = {}) {
showDialog.value = true
if (!Strings.isBlank(data.id)) {
status.value = 'modify'
GoodsApi.detail(data.id!).then((res) => {
formData.$reset(res.data)
if (res.data.picture != null) uploaderIns.value?.setDefaultFiles([ res.data.picture ])
})
} else {
status.value = 'add'
formData.$reset(data)
}
formPanelIns.value?.open(data.id)
},
})
</script>
<style lang="stylus" scoped>
.form-panel {
padding 20px
display: grid;
gap: 0 30px;
.form-items {
grid-template-columns: 1fr 1fr;
grid-template-areas: "picture ." \
"picture ." \
"picture .";
grid-template-columns: 1fr 1fr;
:deep(.el-form-item) {
.el-form-item {
&:first-child {
align-items: start;
grid-area: picture

View File

@ -54,10 +54,11 @@ import CraftApi from '@/pages/mfg/craft/craft-api.ts'
import CraftForm from '@/pages/mfg/craft/CraftForm.vue'
import { ElMessage } from 'element-plus'
import CraftFlow from '@/pages/mfg/craft-flow/CraftFlow.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')

View File

@ -25,10 +25,11 @@
<script lang="ts" setup>
import EndpointApi from '@/pages/sys/endpoint/endpoint-api.ts'
import EndpointForm from '@/pages/sys/endpoint/EndpointForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')

View File

@ -46,10 +46,11 @@
<script lang="ts" setup>
import TplApi from '@/pages/sys/gen/tpl/tpl-api.ts'
import TplForm from '@/pages/sys/gen/tpl/TplForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const defaultSearchForm: TplTypes.SearchTplParam = {

View File

@ -61,10 +61,11 @@ import MenuApi from '@/pages/sys/menus/menu-api.ts'
import MenuForm from '@/pages/sys/menus/MenuForm.vue'
import Strings from '@/common/utils/strings.ts'
import AIcon from '@/components/a-icon/AIcon.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const menuFormIns = useTemplateRef<InstanceType<typeof MenuForm>>('menuForm')

View File

@ -35,10 +35,11 @@ import RoleApi from '@/pages/sys/role/role-api.ts'
import RoleForm from '@/pages/sys/role/RoleForm.vue'
import { ElMessage } from 'element-plus'
import BindRes from '@/pages/sys/role/BindRes.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const roleFormIns = useTemplateRef<InstanceType<typeof RoleForm>>('roleForm')

View File

@ -34,10 +34,11 @@
import SnConfigApi from '@/pages/sys/sn-config/sn-config-api.ts'
import SnConfigForm from '@/pages/sys/sn-config/SnConfigForm.vue'
import Strings from '@/common/utils/strings.ts'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const snConfigFormIns = useTemplateRef<InstanceType<typeof SnConfigForm>>('snConfigForm')

View File

@ -73,10 +73,11 @@ import TaskApi from '@/pages/sys/task/task-api.ts'
import TaskForm from '@/pages/sys/task/TaskForm.vue'
import ScheduleRecodePanel from '@/pages/sys/task/schedule-recode/ScheduleRecodePanel.vue'
import Times from '@/common/utils/times.ts'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')

View File

@ -63,10 +63,11 @@ import BindRole from '@/pages/sys/user/BindRole.vue'
import ClientUtil from '@/common/utils/client-util.ts'
import Strings from '@/common/utils/strings.ts'
import Avatar from '@/assets/images/avatar.png'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const formPageIns = useTemplateRef<ComponentExposed<typeof FormPage>>('formPage')

View File

@ -55,10 +55,11 @@
<script lang="ts" setup>
import InOrderApi from '@/pages/wh/in-order/in-order-api.ts'
import InOrderForm from '@/pages/wh/in-order/InOrderForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const inOrderFormIns = useTemplateRef<InstanceType<typeof InOrderForm>>('inOrderForm')

View File

@ -64,10 +64,11 @@
<script lang="ts" setup>
import InventoryApi from '@/pages/wh/inventory/inventory-api.ts'
import InventoryForm from '@/pages/wh/inventory/InventoryForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const inventoryFormIns = useTemplateRef<InstanceType<typeof InventoryForm>>('inventoryForm')

View File

@ -94,10 +94,11 @@
<script lang="ts" setup>
import OutOrderApi from '@/pages/wh/out-order/out-order-api.ts'
import OutOrderForm from '@/pages/wh/out-order/OutOrderForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const outOrderFormIns = useTemplateRef<InstanceType<typeof OutOrderForm>>('outOrderForm')

View File

@ -63,10 +63,11 @@
<script lang="ts" setup>
import PurchaseOrderApi from '@/pages/wh/purchase-order/purchase-order-api.ts'
import PurchaseOrderForm from '@/pages/wh/purchase-order/PurchaseOrderForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
const purchaseOrderFormIns = useTemplateRef<InstanceType<typeof PurchaseOrderForm>>('purchaseOrderForm')

View File

@ -95,10 +95,11 @@
<script lang="ts" setup>
import SalesOrderApi from '@/pages/wh/sales-order/sales-order-api.ts'
import SalesOrderForm from '@/pages/wh/sales-order/SalesOrderForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const salesOrderFormIns = useTemplateRef<InstanceType<typeof SalesOrderForm>>('salesOrderForm')

View File

@ -55,10 +55,11 @@
<script lang="ts" setup>
import WarehouseApi from '@/pages/wh/warehouse/warehouse-api.ts'
import WarehouseForm from '@/pages/wh/warehouse/WarehouseForm.vue'
import FormPage, {
type ActionColumnType,
type ToolType,
} from '@/components/page/FormPage.vue'
import FormPage from '@/components/page/FormPage.vue'
import type {
ActionColumnType,
ToolType,
} from '@/components/page/a-page-type.ts'
import type { ComponentExposed } from 'vue-component-type-helpers'
const warehouseFormIns = useTemplateRef<InstanceType<typeof WarehouseForm>>('warehouseForm')