Merge branch 'develop' into 'develop'

日常优化

See merge request pisteams/pis!8
This commit is contained in:
allen_xiong
2026-03-23 07:04:55 +00:00
25 changed files with 12249 additions and 1410 deletions
-2
View File
@@ -5,7 +5,5 @@
.history/
.vscode/
web/package-lock.json
web/node_modules
web/dist
*.bat
@@ -1 +0,0 @@
# -*- coding: utf-8 -*-
+12243
View File
File diff suppressed because it is too large Load Diff
-8
View File
@@ -1,8 +0,0 @@
import { request } from '/@/utils/service'
const apiPrefix = '/api/system/companies/'
export const GetList = (params: any) => request({ url: apiPrefix, method: 'get', params })
export const AddObj = (data: any) => request({ url: apiPrefix, method: 'post', data })
export const UpdateObj = (data: any) => request({ url: apiPrefix + data.id + '/', method: 'put', data })
export const DelObj = (id: string | number) => request({ url: apiPrefix + id + '/', method: 'delete' })
-143
View File
@@ -1,143 +0,0 @@
import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
import * as api from './api'
import { useUserInfo } from '/@/stores/userInfo'
import { ElMessage } from 'element-plus'
const statusDict = [
{ value: 1, label: '可用' },
{ value: 0, label: '不可用' }
]
export const createCrudOptions = function ({ crudExpose }: Partial<CreateCrudOptionsProps>): CreateCrudOptionsRet {
void crudExpose
const userStore = useUserInfo()
const currentUser =
userStore.userInfos?.name ||
userStore.userInfos?.username ||
userStore.userInfos?.email ||
''
const ensureCompanyCodeUnique = async (code: string, currentId?: number) => {
if (!code) return
const res = await api.GetList({ company_code: code, page: 1, page_size: 1, pageSize: 1 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
const exists = Array.isArray(list) ? list.find((item: any) => item.company_code === code) : null
if (exists && (!currentId || exists.id !== currentId)) {
throw new Error('公司代码已存在,不可重复')
}
}
return {
crudOptions: {
form: {
labelWidth: '110px',
display: 'flex'
},
request: {
pageRequest: async (query) => api.GetList(query),
addRequest: async ({ form }) =>
{
try {
await ensureCompanyCodeUnique(form.company_code)
return await api.AddObj({
...form,
createuser: currentUser,
updateuser: currentUser
})
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
editRequest: async ({ form, row }) =>
{
try {
await ensureCompanyCodeUnique(form.company_code, row.id)
return await api.UpdateObj({
...form,
id: row.id,
updateuser: currentUser
})
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
delRequest: async ({ row }) => api.DelObj(row.id)
},
table: {
rowKey: 'id'
},
actionbar: {
buttons: {
add: { show: true }
}
},
rowHandle: {
fixed: 'right'
},
columns: {
company_code: {
title: '公司代码',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入公司代码', clearable: true } } },
form: { rules: [{ required: true, message: '请输入公司代码' }] },
column: { minWidth: 140, showOverflowTooltip: true }
},
company_name: {
title: '公司全称',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入公司全称', clearable: true } } },
column: { minWidth: 180, showOverflowTooltip: true }
},
company_short_name: {
title: '公司简称',
type: 'input',
column: { minWidth: 150, showOverflowTooltip: true }
},
company_address: {
title: '公司地址',
type: 'input',
column: { minWidth: 220, showOverflowTooltip: true }
},
status: {
title: '可用状态',
type: 'dict-switch',
dict: dict({ data: statusDict }),
form: { value: 1 },
column: { width: 120 }
},
createuser: {
title: '创建人员',
type: 'input',
form: { show: false },
column: { width: 140, showOverflowTooltip: true }
},
updateuser: {
title: '更新人员',
type: 'input',
form: { show: false },
column: { width: 140, showOverflowTooltip: true }
},
create_datetime: {
title: '创建时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
},
update_datetime: {
title: '更新时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
}
}
}
}
}
-24
View File
@@ -1,24 +0,0 @@
<template>
<fs-page>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script setup lang="ts" name="CompanyMaintenance">
import { ref, onMounted } from 'vue'
import { useCrud, useExpose } from '@fast-crud/fast-crud'
import { createCrudOptions } from './crud'
const crudRef = ref()
const crudBinding = ref()
const { crudExpose } = useExpose({ crudRef, crudBinding })
const { crudOptions } = createCrudOptions({ crudExpose })
useCrud({ crudExpose, crudOptions })
onMounted(() => {
crudExpose?.doRefresh()
})
</script>
<style scoped></style>
-12
View File
@@ -1,12 +0,0 @@
import { request } from '/@/utils/service'
const apiPrefix = '/api/system/currencies/'
export const GetList = (params: any) => request({ url: apiPrefix, method: 'get', params })
export const AddObj = (data: any) => request({ url: apiPrefix, method: 'post', data })
export const UpdateObj = (data: any) => request({ url: apiPrefix + data.id + '/', method: 'put', data })
export const DelObj = (id: string | number) => request({ url: apiPrefix + id + '/', method: 'delete' })
// 用于下拉选择交易厂区(公司代码)
export const GetCompanies = (params: any = { page: 1, pageSize: 200 }) =>
request({ url: '/api/system/companies/', method: 'get', params })
-119
View File
@@ -1,119 +0,0 @@
import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
import * as api from './api'
const statusDict = [
{ value: 1, label: '可用' },
{ value: 0, label: '不可用' }
]
const loadCompanyOptions = async () => {
try {
const res = await api.GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
return (Array.isArray(list) ? list : []).map((c: any) => ({
company_code: c.company_code,
company_short_name: c.company_short_name || c.company_code || c.company_name
}))
} catch (e) {
console.warn('加载公司列表失败', e)
return []
}
}
// 预取一次,确保进入页面时就触发请求
void loadCompanyOptions()
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
void crudExpose
return {
crudOptions: {
form: {
labelWidth: '110px'
},
request: {
pageRequest: async (query) => api.GetList(query),
addRequest: async ({ form }) => api.AddObj(form),
editRequest: async ({ form, row }) => api.UpdateObj({ ...form, id: row.id }),
delRequest: async ({ row }) => api.DelObj(row.id)
},
table: {
rowKey: 'id'
},
actionbar: {
buttons: {
add: { show: true }
}
},
rowHandle: {
fixed: 'right'
},
columns: {
currencyname: {
title: '货币名称',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入货币名称', clearable: true } } },
form: { rules: [{ required: true, message: '请输入货币名称' }] },
column: { minWidth: 160, showOverflowTooltip: true }
},
currencycode: {
title: '货币代码',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入货币代码', clearable: true } } },
column: { minWidth: 140, showOverflowTooltip: true }
},
currencysymbol: {
title: '货币符号',
type: 'input',
form: { rules: [{ required: true, message: '请输入货币符号' }] },
column: { width: 120, showOverflowTooltip: true }
},
factory: {
title: '交易厂区',
type: 'dict-select',
dict: dict({
cache: false,
value: 'company_code',
label: 'company_short_name',
getData: async () => {
return loadCompanyOptions()
}
}),
search: { show: true },
column: { width: 160, showOverflowTooltip: true }
},
tax: {
title: '税率(%)',
type: 'number',
form: { rules: [{ required: true, message: '请输入税率' }], component: { props: { precision: 2 } } },
column: { width: 120 }
},
status: {
title: '可用状态',
type: 'dict-switch',
dict: dict({ data: statusDict }),
form: { value: 1 },
column: { width: 120 }
},
create_datetime: {
title: '创建时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
},
update_datetime: {
title: '更新时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
}
}
}
}
}
@@ -1,24 +0,0 @@
<template>
<fs-page>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script setup lang="ts" name="CurrencyMaintenance">
import { ref, onMounted } from 'vue'
import { useCrud, useExpose } from '@fast-crud/fast-crud'
import { createCrudOptions } from './crud'
const crudRef = ref()
const crudBinding = ref()
const { crudExpose } = useExpose({ crudRef, crudBinding })
const { crudOptions } = createCrudOptions({ crudExpose })
useCrud({ crudExpose, crudOptions })
onMounted(() => {
crudExpose?.doRefresh()
})
</script>
<style scoped></style>
@@ -1,8 +0,0 @@
import { request } from '/@/utils/service'
const apiPrefix = '/api/system/misc_materials/'
export const GetList = (params: any) => request({ url: apiPrefix, method: 'get', params })
export const AddObj = (data: any) => request({ url: apiPrefix, method: 'post', data })
export const UpdateObj = (data: any) => request({ url: apiPrefix + data.id + '/', method: 'put', data })
export const DelObj = (id: string | number) => request({ url: apiPrefix + id + '/', method: 'delete' })
@@ -1,113 +0,0 @@
import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
import * as api from './api'
import { GetCompanies } from '../currency/api'
const statusDict = [
{ value: 1, label: '可用' },
{ value: 0, label: '不可用' }
]
const loadCompanyOptions = async () => {
try {
const res = await GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
return (Array.isArray(list) ? list : []).map((c: any) => ({
company_code: c.company_code,
company_short_name: c.company_short_name || c.company_code || c.company_name
}))
} catch (e) {
console.warn('加载公司列表失败', e)
return []
}
}
// 预取一次,确保进入页面时就触发请求
void loadCompanyOptions()
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
void crudExpose
return {
crudOptions: {
form: {
labelWidth: '110px'
},
request: {
pageRequest: async (query) => api.GetList(query),
addRequest: async ({ form }) => api.AddObj(form),
editRequest: async ({ form, row }) => api.UpdateObj({ ...form, id: row.id }),
delRequest: async ({ row }) => api.DelObj(row.id)
},
table: {
rowKey: 'id'
},
actionbar: {
buttons: {
add: { show: true }
}
},
rowHandle: {
fixed: 'right'
},
columns: {
factory: {
title: '交易厂区',
type: 'dict-select',
dict: dict({
cache: false,
value: 'company_code',
label: 'company_short_name',
getData: async () => {
return loadCompanyOptions()
}
}),
search: { show: true },
column: { minWidth: 160, showOverflowTooltip: true }
},
materialtype: {
title: '材质',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入材质', clearable: true } } },
column: { minWidth: 160, showOverflowTooltip: true }
},
density: {
title: '比重',
type: 'input',
form: { rules: [{ required: true, message: '请输入比重' }] },
column: { width: 120, showOverflowTooltip: true }
},
price: {
title: '单价',
type: 'number',
form: { rules: [{ required: true, message: '请输入单价' }], component: { props: { precision: 2 } } },
column: { width: 120 }
},
status: {
title: '可用状态',
type: 'dict-switch',
dict: dict({ data: statusDict }),
form: { value: 1 },
column: { width: 120 }
},
create_datetime: {
title: '创建时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
},
update_datetime: {
title: '更新时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
}
}
}
}
}
@@ -1,24 +0,0 @@
<template>
<fs-page>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script setup lang="ts" name="MiscMaterialMaintenance">
import { ref, onMounted } from 'vue'
import { useCrud, useExpose } from '@fast-crud/fast-crud'
import { createCrudOptions } from './crud'
const crudRef = ref()
const crudBinding = ref()
const { crudExpose } = useExpose({ crudRef, crudBinding })
const { crudOptions } = createCrudOptions({ crudExpose })
useCrud({ crudExpose, crudOptions })
onMounted(() => {
crudExpose?.doRefresh()
})
</script>
<style scoped></style>
-8
View File
@@ -1,8 +0,0 @@
import { request } from '/@/utils/service'
const apiPrefix = '/api/system/misc_parts/'
export const GetList = (params: any) => request({ url: apiPrefix, method: 'get', params })
export const AddObj = (data: any) => request({ url: apiPrefix, method: 'post', data })
export const UpdateObj = (data: any) => request({ url: apiPrefix + data.id + '/', method: 'put', data })
export const DelObj = (id: string | number) => request({ url: apiPrefix + id + '/', method: 'delete' })
-205
View File
@@ -1,205 +0,0 @@
import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
import * as api from './api'
import { GetCompanies } from '../currency/api'
import { GetList as GetUnits } from '../unit/api'
import { ElMessage } from 'element-plus'
const statusDict = [
{ value: 1, label: '启用' },
{ value: 0, label: '禁用' }
]
const categoryDict = [
{ value: 1, label: '模治具' },
{ value: 2, label: '石墨' },
{ value: 3, label: '其他' }
]
const loadCompanyOptions = async () => {
try {
const res = await GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
return (Array.isArray(list) ? list : []).map((c: any) => ({
company_code: c.company_code,
company_short_name: c.company_short_name || c.company_code || c.company_name
}))
} catch (e) {
console.warn('加载公司列表失败', e)
return []
}
}
const loadUnitOptions = async (companyCode?: string) => {
try {
const params: any = { page: 1, page_size: 500, pageSize: 500 }
if (companyCode) params.factory = companyCode
const res = await GetUnits(params)
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
return (Array.isArray(list) ? list : []).map((u: any) => ({
value: u.unitcode || u.unit_code,
label: u.unitname || u.unit_name || u.unitcode
}))
} catch (e) {
console.warn('加载单位列表失败', e)
return []
}
}
// 预取公司列表
void loadCompanyOptions()
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
void crudExpose
const ensurePartUnique = async (companyCode: string, partId: string, currentId?: number) => {
if (!companyCode || !partId) return
const res = await api.GetList({ company_code: companyCode, partid: partId, page: 1, page_size: 1, pageSize: 1 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
const exists = Array.isArray(list)
? list.find((item: any) => item.company_code === companyCode && item.partid === partId)
: null
if (exists && (!currentId || exists.id !== currentId)) {
throw new Error('同一交易厂区下料号已存在,不可重复')
}
}
return {
crudOptions: {
form: {
labelWidth: '110px'
},
request: {
pageRequest: async (query) => api.GetList(query),
addRequest: async ({ form }) => {
try {
await ensurePartUnique(form.company_code, form.partid)
return await api.AddObj(form)
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
editRequest: async ({ form, row }) => {
try {
await ensurePartUnique(form.company_code, form.partid, row.id)
return await api.UpdateObj({ ...form, id: row.id })
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
delRequest: async ({ row }) => api.DelObj(row.id)
},
table: {
rowKey: 'id'
},
actionbar: {
buttons: {
add: { show: true }
}
},
rowHandle: {
fixed: 'right'
},
columns: {
company_code: {
title: '交易厂区',
type: 'dict-select',
dict: dict({
cache: false,
value: 'company_code',
label: 'company_short_name',
getData: async () => loadCompanyOptions()
}),
search: { show: true },
form: {
component: {
on: {
change({ form, value }: any) {
// 切换厂区时清空单位并触发重新加载
form.unit = undefined
form.company_code = value
}
}
}
},
column: { minWidth: 160, showOverflowTooltip: true }
},
partid: {
title: '料号',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入料号', clearable: true } } },
form: { rules: [{ required: true, message: '请输入料号' }] },
column: { minWidth: 160, showOverflowTooltip: true }
},
partid_name: {
title: '物料说明',
type: 'input',
form: { rules: [{ required: true, message: '请输入物料说明' }] },
column: { minWidth: 160, showOverflowTooltip: true }
},
specification: {
title: '品名规格',
type: 'input',
form: { rules: [{ required: true, message: '请输入品名规格' }] },
column: { minWidth: 160, showOverflowTooltip: true }
},
unit: {
title: '单位',
type: 'dict-select',
dict: dict({
cache: false,
getData: async ({ form }: any = {}) => loadUnitOptions(form?.company_code)
}),
form: { rules: [{ required: true, message: '请选择单位' }], component: { props: { placeholder: '先选择厂区' } } },
column: { width: 140, showOverflowTooltip: true }
},
partid_category_id: {
title: '物料分类',
type: 'dict-select',
dict: dict({ data: categoryDict }),
column: { width: 140, showOverflowTooltip: true }
},
status: {
title: '启用否',
type: 'dict-switch',
dict: dict({ data: statusDict }),
form: { value: 1 },
column: { width: 120 }
},
create_datetime: {
title: '创建时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
},
update_datetime: {
title: '更新时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
}
}
}
}
}
@@ -1,22 +0,0 @@
<template>
<fs-page>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useCrud, useExpose } from '@fast-crud/fast-crud'
import { createCrudOptions } from './crud'
const crudRef = ref()
const crudBinding = ref()
const { crudExpose } = useExpose({ crudRef, crudBinding })
const { crudOptions } = createCrudOptions({ crudExpose })
useCrud({ crudExpose, crudOptions })
onMounted(() => {
crudExpose?.doRefresh()
})
</script>
@@ -1,8 +0,0 @@
import { request } from '/@/utils/service'
const apiPrefix = '/api/system/misc_stations/'
export const GetList = (params: any) => request({ url: apiPrefix, method: 'get', params })
export const AddObj = (data: any) => request({ url: apiPrefix, method: 'post', data })
export const UpdateObj = (data: any) => request({ url: apiPrefix + data.id + '/', method: 'put', data })
export const DelObj = (id: string | number) => request({ url: apiPrefix + id + '/', method: 'delete' })
@@ -1,193 +0,0 @@
import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
import * as api from './api'
import { GetCompanies } from '../currency/api'
import { GetList as GetUnits } from '../unit/api'
import { ElMessage } from 'element-plus'
const statusDict = [
{ value: 1, label: '可用' },
{ value: 0, label: '不可用' }
]
const stationTypeDict = [
{ value: 1, label: '模治具' },
{ value: 2, label: '石墨' }
]
const loadCompanyOptions = async () => {
try {
const res = await GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
return (Array.isArray(list) ? list : []).map((c: any) => ({
company_code: c.company_code,
company_short_name: c.company_short_name || c.company_code || c.company_name
}))
} catch (e) {
console.warn('加载公司列表失败', e)
return []
}
}
const loadUnitOptions = async () => {
try {
const res = await GetUnits({ page: 1, page_size: 1000, pageSize: 1000 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
return (Array.isArray(list) ? list : []).map((u: any) => ({
value: u.unitcode || u.unit_code || u.unit || u.code,
label: u.unitname || u.unit_name || u.unit || u.code
}))
} catch (e) {
console.warn('加载计量单位失败', e)
return []
}
}
// 预取一次,进入页面即触发
void loadCompanyOptions()
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
void crudExpose
const ensureStationCodeUnique = async (companyCode: string, stationCode: string, currentId?: number) => {
if (!companyCode || !stationCode) return
const res = await api.GetList({ company_code: companyCode, stationcode: stationCode, page: 1, page_size: 1, pageSize: 1 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
const exists = Array.isArray(list)
? list.find((item: any) => item.company_code === companyCode && item.stationcode === stationCode)
: null
if (exists && (!currentId || exists.id !== currentId)) {
throw new Error('同一交易厂区下工站代码已存在,不可重复')
}
}
return {
crudOptions: {
form: {
labelWidth: '110px'
},
request: {
pageRequest: async (query) => api.GetList(query),
addRequest: async ({ form }) => {
try {
await ensureStationCodeUnique(form.company_code, form.stationcode)
return await api.AddObj(form)
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
editRequest: async ({ form, row }) => {
try {
await ensureStationCodeUnique(form.company_code, form.stationcode, row.id)
return await api.UpdateObj({ ...form, id: row.id })
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
delRequest: async ({ row }) => api.DelObj(row.id)
},
table: {
rowKey: 'id'
},
actionbar: {
buttons: {
add: { show: true }
}
},
rowHandle: {
fixed: 'right'
},
columns: {
company_code: {
title: '交易厂区',
type: 'dict-select',
dict: dict({
cache: false,
value: 'company_code',
label: 'company_short_name',
getData: async () => loadCompanyOptions()
}),
search: { show: true },
column: { minWidth: 160, showOverflowTooltip: true }
},
stationcode: {
title: '工站代码',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入工站代码', clearable: true } } },
form: { rules: [{ required: true, message: '请输入工站代码' }] },
column: { minWidth: 140, showOverflowTooltip: true }
},
stationname: {
title: '工站名称',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入工站名称', clearable: true } } },
form: { rules: [{ required: true, message: '请输入工站名称' }] },
column: { minWidth: 160, showOverflowTooltip: true }
},
stationtype: {
title: '工站类型',
type: 'dict-select',
dict: dict({ data: stationTypeDict }),
form: { rules: [{ required: true, message: '请选择工站类型' }] },
column: { width: 140, showOverflowTooltip: true }
},
unit: {
title: '计量单位',
type: 'dict-select',
dict: dict({
cache: false,
getData: async () => loadUnitOptions()
}),
form: { rules: [{ required: true, message: '请选择计量单位' }] },
column: { width: 140, showOverflowTooltip: true }
},
rate: {
title: '费率',
type: 'number',
form: { rules: [{ required: true, message: '请输入费率' }], component: { props: { precision: 2 } } },
column: { width: 120 }
},
status: {
title: '可用状态',
type: 'dict-switch',
dict: dict({ data: statusDict }),
form: { value: 1 },
column: { width: 120 }
},
create_datetime: {
title: '创建时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
},
update_datetime: {
title: '更新时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
}
}
}
}
}
@@ -1,24 +0,0 @@
<template>
<fs-page>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script setup lang="ts" name="MiscStationMaintenance">
import { ref, onMounted } from 'vue'
import { useCrud, useExpose } from '@fast-crud/fast-crud'
import { createCrudOptions } from './crud'
const crudRef = ref()
const crudBinding = ref()
const { crudExpose } = useExpose({ crudRef, crudBinding })
const { crudOptions } = createCrudOptions({ crudExpose })
useCrud({ crudExpose, crudOptions })
onMounted(() => {
crudExpose?.doRefresh()
})
</script>
<style scoped></style>
-8
View File
@@ -1,8 +0,0 @@
import { request } from '/@/utils/service'
const apiPrefix = '/api/system/suppliers/'
export const GetList = (params: any) => request({ url: apiPrefix, method: 'get', params })
export const AddObj = (data: any) => request({ url: apiPrefix, method: 'post', data })
export const UpdateObj = (data: any) => request({ url: apiPrefix + data.id + '/', method: 'put', data })
export const DelObj = (id: string | number) => request({ url: apiPrefix + id + '/', method: 'delete' })
-296
View File
@@ -1,296 +0,0 @@
import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
import * as api from './api'
import { GetCompanies } from '../currency/api'
import { GetList as GetCurrencies } from '../currency/api'
import { ElMessage } from 'element-plus'
const statusDict = [
{ value: 1, label: '可用' },
{ value: 0, label: '不可用' }
]
const vendorTypeDict = [
{ value: '国有', label: '国有' },
{ value: '集体', label: '集体' },
{ value: '私营', label: '私营' },
{ value: '合资', label: '合资' },
{ value: '独资', label: '独资' },
{ value: '其他', label: '其他' }
]
const paymentTermDict = [
{ value: 'tt_30_70', label: 'T/T 30%预付,70%出货前' },
{ value: 'net30', label: '月结30天' },
{ value: 'net45', label: '月结45天' },
{ value: 'prepaid', label: '全额预付' }
]
const incotermDict = [
{ value: 'EXW', label: 'EXW(工厂交货)' },
{ value: 'FCA', label: 'FCA(货交承运人)' },
{ value: 'CPT', label: 'CPT(运费付至)' },
{ value: 'CIP', label: 'CIP(运费及保险费付至)' },
{ value: 'DAP', label: 'DAP(目的地交货)' },
{ value: 'DPU', label: 'DPU(卸货地交货)' },
{ value: 'DDP', label: 'DDP(完税后交货)' },
{ value: 'FAS', label: 'FAS(船边交货)' },
{ value: 'FOB', label: 'FOB(船上交货)' },
{ value: 'CFR', label: 'CFR(成本加运费)' },
{ value: 'CIF', label: 'CIF(成本、保险费加运费)' }
]
const loadCompanyOptions = async () => {
try {
const res = await GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
return (Array.isArray(list) ? list : []).map((c: any) => ({
company_code: c.company_code,
company_short_name: c.company_short_name || c.company_code || c.company_name
}))
} catch (e) {
console.warn('加载公司列表失败', e)
return []
}
}
const loadCurrencyOptions = async (companyCode?: string) => {
try {
const params: any = { page: 1, page_size: 500, pageSize: 500 }
if (companyCode) params.factory = companyCode
const res = await GetCurrencies(params)
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
return (Array.isArray(list) ? list : []).map((c: any) => ({
value: c.currencycode || c.currency_code,
label: c.currencyname || c.currency_code || c.currencycode || c.currency_name
}))
} catch (e) {
console.warn('加载币别列表失败', e)
return []
}
}
// 预取一次公司列表
void loadCompanyOptions()
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
void crudExpose
const ensureSupplierUnique = async (companyCode: string, supplierId: string, currentId?: number) => {
if (!companyCode || !supplierId) return
const res = await api.GetList({ company_code: companyCode, supplier_id: supplierId, page: 1, page_size: 1, pageSize: 1 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
const exists = Array.isArray(list)
? list.find((item: any) => item.company_code === companyCode && item.supplier_id === supplierId)
: null
if (exists && (!currentId || exists.id !== currentId)) {
throw new Error('同一交易厂区下供应商代码已存在,不可重复')
}
}
return {
crudOptions: {
form: {
labelWidth: '110px'
},
request: {
pageRequest: async (query) => api.GetList(query),
addRequest: async ({ form }) => {
try {
await ensureSupplierUnique(form.company_code, form.supplier_id)
return await api.AddObj(form)
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
editRequest: async ({ form, row }) => {
try {
await ensureSupplierUnique(form.company_code, form.supplier_id, row.id)
return await api.UpdateObj({ ...form, id: row.id })
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
delRequest: async ({ row }) => api.DelObj(row.id)
},
table: {
rowKey: 'id'
},
actionbar: {
buttons: {
add: { show: true }
}
},
rowHandle: {
fixed: 'right'
},
columns: {
company_code: {
title: '交易厂区',
type: 'dict-select',
dict: dict({
cache: false,
value: 'company_code',
label: 'company_short_name',
getData: async () => loadCompanyOptions()
}),
search: { show: true },
form: {
rules: [{ required: true, message: '请选择交易厂区' }],
component: {
on: {
change({ form, value }: any) {
// 切换厂区时清空币别,触发重新加载
form.transaction_currency = undefined
form.company_code = value
}
}
}
},
column: { minWidth: 160, showOverflowTooltip: true }
},
supplier_id: {
title: '供应商代码/ID',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入供应商代码/ID', clearable: true } } },
form: { rules: [{ required: true, message: '请输入供应商代码/ID' }] },
column: { minWidth: 140, showOverflowTooltip: true }
},
supplier_name: {
title: '供应商全称',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入供应商全称', clearable: true } } },
form: { rules: [{ required: true, message: '请输入供应商全称' }] },
column: { minWidth: 180, showOverflowTooltip: true }
},
supplier_short_name: {
title: '供应商简称',
type: 'input',
form: { rules: [{ required: true, message: '请输入供应商简称' }] },
column: { minWidth: 160, showOverflowTooltip: true }
},
vendor_type: {
title: '厂商性质',
type: 'dict-select',
dict: dict({ data: vendorTypeDict }),
column: { minWidth: 140, showOverflowTooltip: true }
},
payment_terms: {
title: '付款条件',
type: 'dict-select',
dict: dict({ data: paymentTermDict }),
column: { minWidth: 160, showOverflowTooltip: true }
},
transaction_currency: {
title: '交易货币',
type: 'dict-select',
dict: dict({
cache: false,
getData: async ({ form }: any = {}) => {
return loadCurrencyOptions(form?.company_code)
}
}),
form: { placeholder: '先选择交易厂区' },
column: { minWidth: 140, showOverflowTooltip: true }
},
incoterms: {
title: '国际条款',
type: 'dict-select',
dict: dict({ data: incotermDict }),
column: { minWidth: 160, showOverflowTooltip: true }
},
supplier_level: {
title: '供应商等级',
type: 'input',
column: { minWidth: 120, showOverflowTooltip: true }
},
contact_person: {
title: '联络人',
type: 'input',
form: { rules: [{ required: true, message: '请输入联络人' }] },
column: { minWidth: 120, showOverflowTooltip: true }
},
contact_phone: {
title: '联络人电话',
type: 'input',
form: { rules: [{ required: true, message: '请输入联络人电话' }] },
column: { minWidth: 140, showOverflowTooltip: true }
},
contact_email: {
title: '联络人邮箱',
type: 'input',
form: { rules: [{ required: true, message: '请输入联络人邮箱' }] },
column: { minWidth: 180, showOverflowTooltip: true }
},
country: {
title: '国家',
type: 'input',
form: { rules: [{ required: true, message: '请输入国家' }] },
column: { minWidth: 120, showOverflowTooltip: true }
},
province: {
title: '省州',
type: 'input',
form: { rules: [{ required: true, message: '请输入省州' }] },
column: { minWidth: 120, showOverflowTooltip: true }
},
city: {
title: '城市',
type: 'input',
column: { minWidth: 120, showOverflowTooltip: true }
},
address: {
title: '详细地址',
type: 'textarea',
column: { minWidth: 200, showOverflowTooltip: true },
form: { component: { props: { rows: 2 } } }
},
postal_code: {
title: '邮递区号',
type: 'input',
column: { minWidth: 120, showOverflowTooltip: true }
},
status: {
title: '可用状态',
type: 'dict-switch',
dict: dict({ data: statusDict }),
form: { value: 1 },
column: { width: 120 }
},
create_datetime: {
title: '创建时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
},
update_datetime: {
title: '更新时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
}
}
}
}
}
@@ -1,24 +0,0 @@
<template>
<fs-page>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script setup lang="ts" name="SupplierMaintenance">
import { ref, onMounted } from 'vue'
import { useCrud, useExpose } from '@fast-crud/fast-crud'
import { createCrudOptions } from './crud'
const crudRef = ref()
const crudBinding = ref()
const { crudExpose } = useExpose({ crudRef, crudBinding })
const { crudOptions } = createCrudOptions({ crudExpose })
useCrud({ crudExpose, crudOptions })
onMounted(() => {
crudExpose?.doRefresh()
})
</script>
<style scoped></style>
-8
View File
@@ -1,8 +0,0 @@
import { request } from '/@/utils/service'
const apiPrefix = '/api/system/units/'
export const GetList = (params: any) => request({ url: apiPrefix, method: 'get', params })
export const AddObj = (data: any) => request({ url: apiPrefix, method: 'post', data })
export const UpdateObj = (data: any) => request({ url: apiPrefix + data.id + '/', method: 'put', data })
export const DelObj = (id: string | number) => request({ url: apiPrefix + id + '/', method: 'delete' })
-106
View File
@@ -1,106 +0,0 @@
import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud'
import * as api from './api'
import { ElMessage } from 'element-plus'
const statusDict = [
{ value: 1, label: '可用' },
{ value: 0, label: '不可用' }
]
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
void crudExpose
const ensureUnitCodeUnique = async (code: string, currentId?: number) => {
if (!code) return
const res = await api.GetList({ unitcode: code, page: 1, page_size: 1, pageSize: 1 })
const list =
res?.data?.data?.results ||
res?.data?.results ||
res?.data?.list ||
res?.data ||
res?.results ||
res?.list ||
[]
const exists = Array.isArray(list) ? list.find((item: any) => item.unitcode === code) : null
if (exists && (!currentId || exists.id !== currentId)) {
throw new Error('计量单位代码已存在,不可重复')
}
}
return {
crudOptions: {
form: {
labelWidth: '110px'
},
request: {
pageRequest: async (query) => api.GetList(query),
addRequest: async ({ form }) => {
try {
await ensureUnitCodeUnique(form.unitcode)
return await api.AddObj(form)
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
editRequest: async ({ form, row }) => {
try {
await ensureUnitCodeUnique(form.unitcode, row.id)
return await api.UpdateObj({ ...form, id: row.id })
} catch (err: any) {
ElMessage.error(err?.message || '保存失败')
throw err
}
},
delRequest: async ({ row }) => api.DelObj(row.id)
},
table: {
rowKey: 'id'
},
actionbar: {
buttons: {
add: { show: true }
}
},
rowHandle: {
fixed: 'right'
},
columns: {
unitcode: {
title: '计量单位代码',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入计量单位代码', clearable: true } } },
form: { rules: [{ required: true, message: '请输入计量单位代码' }] },
column: { minWidth: 140, showOverflowTooltip: true }
},
unitname: {
title: '计量单位名称',
type: 'input',
search: { show: true, component: { props: { placeholder: '请输入计量单位名称', clearable: true } } },
form: { rules: [{ required: true, message: '请输入计量单位名称' }] },
column: { minWidth: 160, showOverflowTooltip: true }
},
status: {
title: '可用状态',
type: 'dict-switch',
dict: dict({ data: statusDict }),
form: { value: 1 },
column: { width: 120 }
},
create_datetime: {
title: '创建时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
},
update_datetime: {
title: '更新时间',
type: 'datetime',
form: { show: false },
column: { width: 180 }
}
}
}
}
}
-24
View File
@@ -1,24 +0,0 @@
<template>
<fs-page>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script setup lang="ts" name="UnitMaintenance">
import { ref, onMounted } from 'vue'
import { useCrud, useExpose } from '@fast-crud/fast-crud'
import { createCrudOptions } from './crud'
const crudRef = ref()
const crudBinding = ref()
const { crudExpose } = useExpose({ crudRef, crudBinding })
const { crudOptions } = createCrudOptions({ crudExpose })
useCrud({ crudExpose, crudOptions })
onMounted(() => {
crudExpose?.doRefresh()
})
</script>
<style scoped></style>
@@ -406,12 +406,12 @@ import { ElMessage } from 'element-plus'
import { createCrudOptions, normalizeDict } from './crud'
import * as api from './api'
import * as costTemplateApi from '../pricetemplate/api'
import { GetCompanies, GetList as GetCurrencies } from '../../basicinfo/currency/api'
import { GetList as GetParts } from '../../basicinfo/misc-part/api'
import { GetList as GetMaterials } from '../../basicinfo/misc-material/api'
import { GetList as GetSuppliers } from '../../basicinfo/supplier/api'
import { GetList as GetStations } from '../../basicinfo/misc-station/api'
import { GetList as GetUnits } from '../../basicinfo/unit/api'
import { GetCompanies, GetList as GetCurrencies } from '../../pisadmin/basicinfo/currency/api'
import { GetList as GetParts } from '../../pisadmin/miscprocurement/misc-part/api'
import { GetList as GetMaterials } from '../../pisadmin/miscprocurement/misc-material/api'
import { GetList as GetSuppliers } from '../../pisadmin/basicinfo/supplier/api'
import { GetList as GetStations } from '../../pisadmin/miscprocurement/misc-station/api'
import { GetList as GetUnits } from '../../pisadmin/basicinfo/unit/api'
import { useUserInfo } from '/@/stores/userInfo'
const crudRef = ref()