@@ -0,0 +1,154 @@ | |||
pipeline{ | |||
agent any | |||
parameters { | |||
choice( | |||
description: 'pztjwebi:开发环境1', | |||
name: 'environment', | |||
choices: ['pztj'] | |||
) | |||
choice( | |||
description: '前端or后端', | |||
name: 'projectqh', | |||
choices: ['backend','frontend'] | |||
) | |||
choice( | |||
description: '执行操作(发布|回滚)', | |||
name: 'operation', | |||
choices: ['develop', 'rollback'] | |||
) | |||
choice( | |||
description: '分支名', | |||
name: 'branchName', | |||
choices: ['master'] | |||
) | |||
string( | |||
name: 'tag', | |||
defaultValue: '', | |||
description: '版本tag' | |||
) | |||
} | |||
stages | |||
{ | |||
stage('Prepare') { | |||
steps { | |||
script{ | |||
echo "1.Prepare Stage" | |||
echo "当前环境${params.environment}" | |||
if(params.operation=='develop') | |||
{ | |||
checkout scm | |||
script { | |||
build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() | |||
if (env.BRANCH_NAME != 'master') { | |||
build_tag = "${env.BRANCH_NAME}-${build_tag}" | |||
} | |||
} | |||
} | |||
else{ | |||
script { | |||
if(params.branchName!= 'master') | |||
{ | |||
build_tag = "${params.branchName}-${params.tag}" | |||
} | |||
else | |||
{ | |||
build_tag="${params.tag}" | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
stage('Test') { | |||
steps { | |||
script{ | |||
echo "2.Test Stage" | |||
} | |||
} | |||
} | |||
stage('Build') { | |||
steps { | |||
script{ | |||
echo "3.Build Docker Image Stage" | |||
if(params.operation=='develop') | |||
{ | |||
if(params.projectqh=='backend') | |||
{ | |||
sh "cp -r backend/* ./" | |||
sh "docker build -f backend/dockerfile -t 10.2.1.24:10242/bpa/pztjapi:${build_tag} ." | |||
} | |||
else if(params.projectqh=='frontend') | |||
{ | |||
sh "docker build -f frontend/dockerfile -t 10.2.1.24:10242/bpa/pztjweb:${build_tag} ." | |||
} | |||
} | |||
} | |||
} | |||
} | |||
stage('Push') { | |||
steps { | |||
script{ | |||
echo "4.Push Docker Image Stage" | |||
withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'harborPassword', usernameVariable: 'harborUser')]) { | |||
sh "docker login -u ${harborUser} -p ${harborPassword} 10.2.1.24:10242" | |||
if(params.operation=='develop') | |||
{ | |||
if(params.projectqh=='backend') | |||
{ | |||
sh "docker push 10.2.1.24:10242/bpa/pztjapi:${build_tag}" | |||
} | |||
else if(params.projectqh=='frontend') | |||
{ | |||
sh "docker push 10.2.1.24:10242/bpa/pztjweb:${build_tag}" | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
stage('Deploy') { | |||
steps { | |||
script{ | |||
echo "5. Deploy Stage" | |||
// if(params.environment=='test') | |||
// { | |||
// input "确认要部署线上环境吗?" | |||
// } | |||
if(params.projectqh=='backend') | |||
{ | |||
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s_pztjapi.yaml" | |||
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s_pztjapi.yaml" | |||
sh "sed -i 's/<NAMESPACES>/${params.environment}/' k8s_pztjapi.yaml" | |||
sh "kubectl apply -f k8s_pztjapi.yaml --record" | |||
} | |||
else if(params.projectqh=='frontend') | |||
{ | |||
sh "sed -i 's/<BUILD_TAG>/${build_tag}/' k8s_pztjweb.yaml" | |||
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' k8s_pztjweb.yaml" | |||
sh "sed -i 's/<NAMESPACES>/${params.environment}/' k8s_pztjweb.yaml" | |||
sh "kubectl apply -f k8s_pztjweb.yaml --record" | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<configuration> | |||
<packageSources> | |||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json"/> | |||
<add key="bpa" value="http://10.2.1.25:10243/repository/bpa/index.json"/> | |||
</packageSources> | |||
</configuration> |
@@ -0,0 +1,13 @@ | |||
server { | |||
listen 80; | |||
server_name localhost; | |||
location / { | |||
root /usr/share/nginx/html; | |||
index index.html index.htm; | |||
try_files $uri $uri/ /index.html; | |||
} | |||
} | |||
@@ -0,0 +1,4 @@ | |||
FROM nginx:latest | |||
COPY ./frontend/dist /usr/share/nginx/html/ | |||
COPY ./frontend/default.conf /etc/nginx/conf.d/ | |||
EXPOSE 80 |
@@ -0,0 +1,16 @@ | |||
*{ | |||
margin: 0; | |||
padding: 0; | |||
} | |||
.container{ | |||
display: flex; | |||
justify-content:space-around; | |||
} | |||
.left { | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: space-around | |||
} |
@@ -0,0 +1,444 @@ | |||
// 桶管理 | |||
import './index.less' | |||
import type { ActionType, ProColumns } from '@ant-design/pro-components'; | |||
import { ProTable } from '@ant-design/pro-components'; | |||
import { Button, Modal, Form, Input, message, Popconfirm, Tag, QRCode, Table } from 'antd'; | |||
import { useRef, useState } from 'react'; | |||
import type { ColumnsType } from 'antd/es/table'; | |||
import DeviceInfoAPI from '@/api/DeviceInfo'; | |||
const bucket = () => { | |||
//表单 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [typeForm] = Form.useForm(); | |||
// 下拉列表 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [modelTitle, setModelTitle] = useState<string>(); | |||
//编辑/新增弹窗 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [isModalOpen, setIsModalOpen] = useState(false); | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const actionRef = useRef<ActionType>(); | |||
// 二维码下载弹窗 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [isopenshow, setopenshow] = useState(false); | |||
// 下载回显的数据 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [information, setinformation] = useState<DeviceTypes.Info>(); | |||
// 桶记录弹窗 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [isrecord, setrecord] = useState(false) | |||
const columns: ProColumns<DeviceTypes.Info>[] = [ | |||
{ | |||
title: 'id', | |||
dataIndex: 'id', | |||
tip: '规则名称是唯一的 key', | |||
hideInSearch: true, | |||
hideInTable: true, | |||
}, | |||
{ | |||
title: '桶名称', | |||
dataIndex: 'name', | |||
ellipsis: true, | |||
}, | |||
{ | |||
title: '桶编号', | |||
dataIndex: 'code', | |||
hideInSearch: true, | |||
ellipsis: true, | |||
}, | |||
{ | |||
title: '当前原料', | |||
dataIndex: 'des', | |||
ellipsis: true, | |||
hideInSearch: true, | |||
}, | |||
{ | |||
title: '桶二维码', | |||
dataIndex: 'type', | |||
ellipsis: true, | |||
hideInSearch: true, | |||
}, | |||
{ | |||
title: '操作', | |||
valueType: 'option', | |||
key: 'option', | |||
align:'center', | |||
render: (_, record) => [ | |||
<Button | |||
key="edit" | |||
type="primary" ghost | |||
onClick={async () => { | |||
setIsModalOpen(true); | |||
setModelTitle('编辑信息'); | |||
const copyFormData = JSON.parse(JSON.stringify(record)); | |||
copyFormData.state = copyFormData.state === '0'; | |||
typeForm.setFieldsValue(copyFormData); | |||
}} | |||
> | |||
编辑 | |||
</Button>, | |||
<Button | |||
key="xz" | |||
type="primary" ghost | |||
onClick={async () => { | |||
setopenshow(true); | |||
setinformation(record) | |||
}} | |||
> | |||
下载 | |||
</Button>, | |||
<Button | |||
key="jl" | |||
type="primary" ghost | |||
onClick={async () => { | |||
setrecord(true) | |||
setinformation(record); | |||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | |||
chart(); | |||
}} | |||
> | |||
记录 | |||
</Button>, | |||
<Popconfirm | |||
key="del" | |||
title="确定要删除此条数据吗?" | |||
onConfirm={() => { | |||
const EnablejsonData: DeviceTypes.Info = { | |||
id: record.id, | |||
name: '', | |||
code: '' | |||
}; | |||
DeviceInfoAPI.Del(EnablejsonData).then((r) => { | |||
if (r.statusCode === 200) { | |||
message.success(r.statusCode === 200 ? '删除成功' : r.message); | |||
actionRef.current?.reload(); | |||
} | |||
}); | |||
}} | |||
onCancel={() => { | |||
message.info('已取消删除'); | |||
}} | |||
okText="确认" | |||
cancelText="关闭" | |||
> | |||
<Button type="primary" danger ghost>删除</Button> | |||
</Popconfirm>, | |||
], | |||
}, | |||
]; | |||
// 定义桶记录里面的列表 | |||
const data:ColumnsType<DeviceTypes.Info> = [ | |||
{ | |||
title: 'id', | |||
dataIndex: 'id', | |||
// tip: '规则名称是唯一的 key', | |||
hideInSearch: true, | |||
hideInTable: true, | |||
}, | |||
{ | |||
title: '工单ID', | |||
dataIndex: 'name', | |||
key: 'name', | |||
align:'center' | |||
}, | |||
{ | |||
title: '工单名称', | |||
dataIndex: 'age', | |||
key: 'age', | |||
align:'center', | |||
ellipsis: true, | |||
}, | |||
{ | |||
title: '原料', | |||
dataIndex: 'age1', | |||
key: 'age1', | |||
align:'center' | |||
}, | |||
{ | |||
title: '原料重量', | |||
dataIndex: 'age2', | |||
key: 'age2', | |||
align:'center' | |||
}, | |||
{ | |||
title: '时间', | |||
dataIndex: 'age3', | |||
key: 'age3', | |||
align:'center' | |||
} | |||
]; | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
// const [aaadata, setaaadata] = useState() | |||
// 桶记录内的列表状态 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [condition,setcondition] = useState() | |||
// 定义一个桶函数 | |||
const chart =async ()=>{ | |||
// 自定义属性 | |||
const chartcheet: DeviceTypes.Page = { | |||
pageIndex: 1, | |||
pageSize: 10, | |||
name: '', | |||
id: '', | |||
code: '' | |||
}; | |||
// const response = await DeviceInfoAPI.PagedList(bbbbbb);; | |||
// if (response.statusCode === 200) { | |||
// setaaadata(response.data.items) | |||
// } | |||
try { | |||
// 调用接口 | |||
const response = await DeviceInfoAPI.PagedList(chartcheet); | |||
// 如果调用成功 | |||
if (response.statusCode === 200) { | |||
// console.log(response); | |||
// 将数据更新到列表最新状态 | |||
setcondition(response.data.items); | |||
} | |||
} catch (error) { | |||
console.error('Error fetching data:', error); | |||
} | |||
} | |||
// 表单提交 | |||
const OnSubmit = async (values: DeviceTypes.Info) => { | |||
if (values.id) { | |||
const response = await DeviceInfoAPI.Update(values); | |||
if (response.statusCode === 200) { | |||
message.success('修改成功'); | |||
actionRef.current?.reload(); | |||
setIsModalOpen(false); | |||
} else { | |||
message.error(JSON.stringify(response.errors) || '修改失败'); | |||
} | |||
} else { | |||
const response = await DeviceInfoAPI.Add(values); | |||
console.log('response', response); | |||
if (response.statusCode === 200) { | |||
message.success('添加成功'); | |||
actionRef.current?.reload(); | |||
setIsModalOpen(false); | |||
} else { | |||
message.error(JSON.stringify(response.errors) || '添加失败'); | |||
} | |||
} | |||
}; | |||
return ( | |||
<> | |||
<ProTable<DeviceTypes.Info> | |||
key="myTable" | |||
columns={columns} | |||
actionRef={actionRef} | |||
cardBordered | |||
request={async (params = {}) => { | |||
const jsonData: DeviceTypes.Page = { | |||
pageIndex: params.current || 1, | |||
pageSize: params.pageSize || 10, | |||
name: params.name || '', | |||
id: '', | |||
code: '' | |||
}; | |||
const response = await DeviceInfoAPI.PagedList(jsonData); | |||
if (response.statusCode === 200) { | |||
return { | |||
data: response.data.items, | |||
success: true, | |||
total: response.data.total, | |||
}; | |||
} else { | |||
return { | |||
data: [], | |||
success: false, | |||
total: 0, | |||
}; | |||
} | |||
}} | |||
rowKey="id" | |||
pagination={{ | |||
pageSize: 10, | |||
}} | |||
dateFormatter="string" | |||
headerTitle="桶列表" | |||
toolBarRender={() => [ | |||
<Button | |||
key="button" | |||
type="primary" | |||
onClick={() => { | |||
typeForm.resetFields(); | |||
setIsModalOpen(true); | |||
setModelTitle('新增桶'); | |||
}} | |||
> | |||
新增桶 | |||
</Button>, | |||
]} | |||
/> | |||
<Modal | |||
key="01" | |||
width={800} | |||
title={<Tag color="#cd201f">{modelTitle}</Tag>} | |||
open={isModalOpen} | |||
onCancel={() => { | |||
setIsModalOpen(false); | |||
}} | |||
footer={[ | |||
<Button | |||
key="back" | |||
onClick={() => { | |||
setIsModalOpen(false); | |||
}} | |||
> | |||
返回 | |||
</Button>, | |||
<Button key="submit" form="myForm" type="primary" htmlType="submit"> | |||
提交 | |||
</Button>, | |||
]} | |||
> | |||
<Form | |||
form={typeForm} | |||
name="basic" | |||
id="myForm" | |||
// lCol={{ span: 4 }} | |||
wrapperCol={{ span: 12 }} | |||
onFinish={OnSubmit} | |||
autoComplete="off" | |||
> | |||
<Form.Item label="id" name="id" hidden> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item | |||
label="桶名称" | |||
name="name" | |||
rules={[{ required: true, message: '此项为必填项!' }]} | |||
> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item label="桶编号" name="code" rules={[{ required: true, message: '此项为必填项!' }]} > | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item label="当前原料" name="code2" rules={[{ required: true, message: '此项为必填项!' }]} > | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item label="桶二维码" name="des" > | |||
<Input /> | |||
</Form.Item> | |||
</Form> | |||
</Modal> | |||
{/* 下载二维码 */} | |||
<Modal | |||
key="xzModal" | |||
width={400} | |||
title={<Tag color="#cd201f">二维码</Tag>} | |||
open={isopenshow} | |||
onCancel={() => { | |||
setopenshow(false); | |||
}} | |||
footer={[ | |||
<Button | |||
key="back" | |||
onClick={() => { | |||
setopenshow(false); | |||
}} | |||
> | |||
返回 | |||
</Button>, | |||
]} | |||
> | |||
<div className='container'> | |||
<div className='left'> | |||
<div className='cod'>桶编号 : {information?.code}</div> | |||
<div className='na'>桶名称 : {information?.name}</div> | |||
<div className='mi'>当前原料 : </div> | |||
</div> | |||
<div className='right'> | |||
<div id="myqrcode" > | |||
<QRCode value="https://ant.design/" style={{ border: 'none' }} /> | |||
</div> | |||
</div> | |||
</div> | |||
</Modal> | |||
{/* 桶记录 */} | |||
<Modal | |||
key="tjl01" | |||
width={800} | |||
title={<Tag color="#cd201f">桶记录</Tag>} | |||
open={isrecord} | |||
onCancel={() => { | |||
setrecord(false) | |||
}} | |||
footer={[ | |||
<Button | |||
key="back" | |||
onClick={() => { | |||
setrecord(false) | |||
}} | |||
> | |||
返回 | |||
</Button>, | |||
]} | |||
> | |||
<div> | |||
<div>桶编号 : {information?.code} </div> | |||
<div>桶名称 :{information?.name} </div> | |||
<Table columns={data} dataSource={condition} /> | |||
</div> | |||
</Modal> | |||
</> | |||
); | |||
}; | |||
export default bucket; |
@@ -0,0 +1,4 @@ | |||
*{ | |||
margin: 0; | |||
padding: 0; | |||
} |
@@ -0,0 +1,282 @@ | |||
// 成品管理 | |||
import type { ActionType, ProColumns } from '@ant-design/pro-components'; | |||
import { ProTable } from '@ant-design/pro-components'; | |||
import { Button, Modal, Form, Input, message, Popconfirm, TreeSelect, Select, Tag, Dropdown, Space, MenuProps } from 'antd'; | |||
import { useRef, useState } from 'react'; | |||
import DeviceInfoAPI from '@/api/DeviceInfo'; | |||
import { DownOutlined } from '@ant-design/icons'; | |||
import FormItem from 'antd/lib/form/FormItem'; | |||
import { ItemType } from 'rc-menu/lib/interface'; | |||
const final = () => { | |||
//定于表单 | |||
const [typeForm] = Form.useForm(); | |||
// 定义新增弹窗 | |||
const [isModalOpen, setIsModalOpen] = useState(false); | |||
// 定义编辑弹窗 | |||
const actionRef = useRef<ActionType>(); | |||
// 定义title | |||
const [modelTitle, setModelTitle] = useState<string>(); | |||
// 定义列表数据 | |||
const columns: ProColumns<DeviceTypes.Info>[] = [ | |||
{ | |||
title: 'id', | |||
dataIndex: 'id', | |||
tip: '规则名称是唯一的 key', | |||
hideInSearch: true, | |||
hideInTable: true, | |||
}, | |||
{ | |||
title: '成品编号', | |||
dataIndex: 'code', | |||
hideInSearch: false, | |||
ellipsis: true, | |||
}, | |||
{ | |||
title: '成品名称', | |||
dataIndex: 'name', | |||
hideInSearch: false, | |||
ellipsis: true, | |||
}, | |||
{ | |||
title: '成品配方', | |||
dataIndex: 'pf', | |||
ellipsis: true, | |||
hideInSearch: true, | |||
}, | |||
{ | |||
title: '成品工艺', | |||
dataIndex: 'gy', | |||
ellipsis: true, | |||
hideInSearch: true, | |||
}, | |||
{ | |||
title: '操作', | |||
valueType: 'option', | |||
key: 'option', | |||
render: (_, record) => [ | |||
<Button | |||
key="edit" | |||
type="primary" ghost | |||
onClick={async () => { | |||
setIsModalOpen(true); | |||
setModelTitle('成品编辑'); | |||
const copyFormData = JSON.parse(JSON.stringify(record)); | |||
copyFormData.state = copyFormData.state === '0'; | |||
typeForm.setFieldsValue(copyFormData); | |||
}} | |||
> | |||
编辑 | |||
</Button>, | |||
<Popconfirm | |||
key="del" | |||
title="确定要删除此条数据吗?" | |||
onConfirm={() => { | |||
const EnablejsonData: DeviceTypes.Info = { | |||
id: record.id, | |||
name: '', | |||
code: '' | |||
}; | |||
DeviceInfoAPI.Del(EnablejsonData).then((r) => { | |||
if (r.statusCode === 200) { | |||
message.success(r.statusCode === 200 ? '删除成功' : r.message); | |||
actionRef.current?.reload(); | |||
} | |||
}); | |||
}} | |||
onCancel={() => { | |||
message.info('已取消删除'); | |||
}} | |||
okText="确认" | |||
cancelText="关闭" | |||
> | |||
<Button type="primary" danger ghost>删除</Button> | |||
</Popconfirm>, | |||
], | |||
}, | |||
]; | |||
const OnSubmit = async (values: DeviceTypes.Info) => { | |||
if (values.id) { | |||
const response = await DeviceInfoAPI.Update(values); | |||
if (response.statusCode === 200) { | |||
message.success('修改成功'); | |||
actionRef.current?.reload(); | |||
setIsModalOpen(false); | |||
} else { | |||
message.error(JSON.stringify(response.errors) || '修改失败'); | |||
} | |||
} else { | |||
const response = await DeviceInfoAPI.Add(values); | |||
console.log('response', response); | |||
if (response.statusCode === 200) { | |||
message.success('添加成功'); | |||
actionRef.current?.reload(); | |||
setIsModalOpen(false); | |||
} else { | |||
message.error(JSON.stringify(response.errors) || '添加失败'); | |||
} | |||
} | |||
}; | |||
// 定义配方列表的数据 | |||
// const item: MenuProps['items'] = [ | |||
// { | |||
// label: 'hini', | |||
// key: '1', | |||
// }, | |||
// { | |||
// label: 'eer ', | |||
// key: '2', | |||
// } | |||
// ]; | |||
// 定义工艺列表 | |||
const areas = [ | |||
{ label: '工艺1', value: '工艺1' }, | |||
{ label: '工艺2', value: '工艺1' }, | |||
]; | |||
// 定义配方列表 | |||
const formula = [ | |||
{ label: '配方1', value: '配方1' }, | |||
{ label: '配方2', value: '配方1' }, | |||
]; | |||
return ( | |||
<> | |||
<ProTable<DeviceTypes.Info> | |||
key="myTable" | |||
columns={columns} | |||
actionRef={actionRef} | |||
cardBordered | |||
// 调用接口判断 | |||
request={async (params = {}) => { | |||
const jsonData: DeviceTypes.Page = { | |||
pageIndex: params.current || 1, | |||
pageSize: params.pageSize || 10, | |||
name: params.name || '', | |||
id: '', | |||
code: '' | |||
}; | |||
const response = await DeviceInfoAPI.PagedList(jsonData); | |||
if (response.statusCode === 200) { | |||
return { | |||
data: response.data.items, | |||
success: true, | |||
total: response.data.total, | |||
}; | |||
} else { | |||
return { | |||
data: [], | |||
success: false, | |||
total: 0, | |||
}; | |||
} | |||
}} | |||
rowKey="id" | |||
pagination={{ | |||
pageSize: 10, | |||
}} | |||
dateFormatter="string" | |||
headerTitle="成品列表" | |||
toolBarRender={() => [ | |||
<Button | |||
key="button" | |||
type="primary" | |||
onClick={() => { | |||
typeForm.resetFields(); | |||
setIsModalOpen(true); | |||
setModelTitle('新增成品'); | |||
}} | |||
> | |||
新增成品 | |||
</Button>, | |||
]} | |||
/> | |||
{/* 新增成品的model弹窗 */} | |||
<Modal | |||
key="01" | |||
width={800} | |||
title={<Tag color="#cd201f">{modelTitle}</Tag>} | |||
open={isModalOpen} | |||
onCancel={() => { | |||
setIsModalOpen(false); | |||
}} | |||
footer={[ | |||
<Button | |||
key="back" | |||
onClick={() => { | |||
setIsModalOpen(false); | |||
}} | |||
> | |||
返回 | |||
</Button>, | |||
<Button key="submit" form="myForm" type="primary" htmlType="submit"> | |||
提交 | |||
</Button>, | |||
]} | |||
> | |||
{/* 新增成品表单 */} | |||
<Form | |||
form={typeForm} | |||
name="basic" | |||
id="myForm" | |||
lCol={{ span: 4 }} | |||
wrapperCol={{ span: 12 }} | |||
onFinish={OnSubmit} | |||
autoComplete="off" | |||
> | |||
<Form.Item label="id" name="id" hidden> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item | |||
label="成品编码" | |||
name="code" | |||
rules={[{ required: true, message: '此项为必填项!' }]} | |||
> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item name="name" label="成品名称" rules={[{ required: true, message: 'Missing area' }]}> | |||
<Input /> | |||
</Form.Item> | |||
{/* 工艺列表 */} | |||
<Form.Item name="gy" label="成品工艺" rules={[{ required: true, message: 'Missing area' }]}> | |||
<Select options={areas} /> | |||
</Form.Item> | |||
{/* 配方列表 */} | |||
<Form.Item name="pf" label="成品配方" rules={[{ required: true, message: 'Missing area' }]}> | |||
<Select options={formula} /> | |||
</Form.Item> | |||
</Form> | |||
</Modal> | |||
</> | |||
); | |||
}; | |||
export default final; |
@@ -0,0 +1,247 @@ | |||
// 分组页面 | |||
import type { ActionType, ProColumns } from '@ant-design/pro-components'; | |||
import { ProTable } from '@ant-design/pro-components'; | |||
import { Button, Modal, Form, Input, message, Popconfirm, Tag, QRCode, Table } from 'antd'; | |||
import { useRef, useState } from 'react'; | |||
import type { ColumnsType } from 'antd/es/table'; | |||
import DeviceInfoAPI from '@/api/DeviceInfo'; | |||
const group = () => { | |||
// 4.定义编辑/新增的弹窗 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [isModalOpen, setIsModalOpen] = useState(false); | |||
// 下拉 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [modelTitle, setModelTitle] = useState<string>(); | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const actionRef = useRef<ActionType>(); | |||
// 6.定义表单 | |||
// eslint-disable-next-line react-hooks/rules-of-hooks | |||
const [typeForm] = Form.useForm(); | |||
// 1.定义列 | |||
const columns: ProColumns<DeviceTypes.Info>[] = [ | |||
{ | |||
title: 'id', | |||
dataIndex: 'id', | |||
tip: '规则名称是唯一的 key', | |||
hideInSearch: true, | |||
hideInTable: true, | |||
}, | |||
{ | |||
title: '分组名称', | |||
dataIndex: 'name', | |||
ellipsis: true, | |||
align: 'center' | |||
}, | |||
{ | |||
title: '分组描述', | |||
dataIndex: 'code', | |||
hideInSearch: true, | |||
ellipsis: true, | |||
align: 'center' | |||
}, | |||
{ | |||
title: '操作', | |||
valueType: 'option', | |||
key: 'option', | |||
align: 'center', | |||
// 4.操作内有两个按钮 | |||
render: (_, record) => [ | |||
<Button | |||
key="edit" | |||
type="primary" ghost | |||
onClick={async () => { | |||
setIsModalOpen(true); | |||
setModelTitle('编辑分组'); | |||
const copyFormData = JSON.parse(JSON.stringify(record)); | |||
typeForm.setFieldsValue(copyFormData); | |||
}} | |||
>编辑 | |||
</Button>, | |||
// 删除 | |||
<Popconfirm | |||
key="del" | |||
title="确定要删除此条数据吗?" | |||
onConfirm={() => { | |||
const EnablejsonData: DeviceTypes.Info = { | |||
id: record.id, | |||
name: '', | |||
code: '' | |||
}; | |||
DeviceInfoAPI.Del(EnablejsonData).then((r) => { | |||
if (r.statusCode === 200) { | |||
message.success(r.statusCode === 200 ? '删除成功' : r.message); | |||
actionRef.current?.reload(); | |||
} | |||
}); | |||
}} | |||
onCancel={() => { | |||
message.info('已取消删除'); | |||
}} | |||
okText="确认" | |||
cancelText="关闭" | |||
> | |||
<Button type="primary" danger ghost>删除</Button> | |||
</Popconfirm>, | |||
] | |||
}, | |||
]; | |||
// 7.定义表单提交 | |||
// 表单提交 | |||
const OnSubmit = async (values: DeviceTypes.Info) => { | |||
if (values.id) { | |||
const response = await DeviceInfoAPI.Update(values); | |||
if (response.statusCode === 200) { | |||
message.success('修改成功'); | |||
actionRef.current?.reload(); | |||
setIsModalOpen(false); | |||
} else { | |||
message.error(JSON.stringify(response.errors) || '修改失败'); | |||
} | |||
} else { | |||
const response = await DeviceInfoAPI.Add(values); | |||
console.log('response', response); | |||
if (response.statusCode === 200) { | |||
message.success('添加成功'); | |||
actionRef.current?.reload(); | |||
setIsModalOpen(false); | |||
} else { | |||
message.error(JSON.stringify(response.errors) || '添加失败'); | |||
} | |||
} | |||
}; | |||
return ( | |||
<> | |||
{/* 2.列的展现 */} | |||
<ProTable<DeviceTypes.Info> | |||
key="myTable" | |||
columns={columns} | |||
actionRef={actionRef} | |||
cardBordered | |||
// 3.调用列接口 | |||
request={async (params = {}) => { | |||
const jsonData: DeviceTypes.Page = { | |||
pageIndex: params.current || 1, | |||
pageSize: params.pageSize || 10, | |||
name: params.name || '', | |||
id: '', | |||
code: '' | |||
}; | |||
const response = await DeviceInfoAPI.PagedList(jsonData); | |||
if (response.statusCode === 200) { | |||
return { | |||
data: response.data.items, | |||
success: true, | |||
total: response.data.total, | |||
}; | |||
} else { | |||
return { | |||
data: [], | |||
success: false, | |||
total: 0, | |||
}; | |||
} | |||
}} | |||
// 展示的页数 | |||
rowKey="id" | |||
pagination={{ | |||
pageSize: 10, | |||
}} | |||
dateFormatter="string" | |||
headerTitle="分组列表" | |||
toolBarRender={() => [ | |||
<Button | |||
key="button" | |||
type="primary" | |||
onClick={() => { | |||
typeForm.resetFields(); | |||
setIsModalOpen(true); | |||
setModelTitle('新增分组'); | |||
}} | |||
> | |||
新增分组 | |||
</Button>, | |||
]} | |||
/> | |||
{/* 5.弹窗 */} | |||
<Modal | |||
key="01" | |||
width={800} | |||
title={<Tag color="#cd201f">{modelTitle}</Tag>} | |||
open={isModalOpen} | |||
onCancel={() => { | |||
setIsModalOpen(false); | |||
}} | |||
footer={[ | |||
<Button | |||
key="back" | |||
onClick={() => { | |||
setIsModalOpen(false); | |||
}} | |||
> | |||
返回 | |||
</Button>, | |||
<Button key="submit" form="myForm" type="primary" htmlType="submit"> | |||
提交 | |||
</Button>, | |||
]} | |||
> | |||
{/* 弹窗内的表单 */} | |||
<Form | |||
form={typeForm} | |||
name="basic" | |||
id="myForm" | |||
labelAlign='right' | |||
// lCol={{ span: 4 }} | |||
wrapperCol={{ span: 12 }} | |||
onFinish={OnSubmit} | |||
autoComplete="off" | |||
> | |||
<Form.Item label="id" name="id" hidden> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item | |||
label="分组名称" | |||
name="name" | |||
rules={[{ required: true, message: '此项为必填项!' }]} | |||
> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item label="分组描述" name="code" rules={[{ required: true, message: '此项为必填项!' }]} > | |||
<Input /> | |||
</Form.Item> | |||
</Form> | |||
</Modal> | |||
</> | |||
) | |||
} | |||
export default group |
@@ -0,0 +1,37 @@ | |||
@primary-color: '#13C2C2'; | |||
.tag { | |||
height: 100%; | |||
width: 100%; | |||
&_item { | |||
padding: 0 5px 0 20px; | |||
height: 72px; | |||
position: relative; | |||
cursor: pointer; | |||
display: -ms-flexbox; | |||
display: flex; | |||
-ms-flex-align: center; | |||
align-items: center; | |||
&_active { | |||
position: absolute; | |||
width: 3px; | |||
height: 72px; | |||
left: 0; | |||
top: 0; | |||
background-color: #13C2C2; | |||
} | |||
&_activeItem{ | |||
background-color: #f7f8fa;; | |||
} | |||
&_editicon{ | |||
position: absolute; | |||
right: 0; | |||
top: 0; | |||
bottom: 0; | |||
display: flex; | |||
align-items: center; | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,268 @@ | |||
// 料仓基础信息 | |||
import type { ActionType, ProColumns } from '@ant-design/pro-components'; | |||
import { ProTable } from '@ant-design/pro-components'; | |||
import { Button, Modal, Form, Input, message, Popconfirm, Transfer, Tag, Col } from 'antd'; | |||
import { useRef, useState, useEffect } from 'react'; | |||
// import { history } from '@umijs/max'; | |||
import DeviceInfoAPI from '@/api/DeviceInfo'; | |||
// import RecipeAPI from '@/api/recipeService' | |||
// import { TransferDirection } from 'antd/es/transfer'; | |||
// interface RecordType { | |||
// key: string; | |||
// title: string; | |||
// description: string; | |||
// chosen: boolean; | |||
// } | |||
// let selectRecordId :string; | |||
export default () => { | |||
//表单 | |||
const [typeForm] = Form.useForm(); | |||
//下拉列表 | |||
// const [isMaterialModalOpen, setIsMaterialModalOpen] = useState(false); | |||
const [modelTitle, setModelTitle] = useState<string>(); | |||
//编辑/新增弹窗 | |||
const [isModalOpen, setIsModalOpen] = useState(false); | |||
const actionRef = useRef<ActionType>(); | |||
const columns: ProColumns<DeviceTypes.Info>[] = [ | |||
{ | |||
title: 'id', | |||
dataIndex: 'id', | |||
tip: '规则名称是唯一的 key', | |||
hideInSearch: true, | |||
hideInTable: true, | |||
}, | |||
{ | |||
title: '料仓名称', | |||
dataIndex: 'name', | |||
ellipsis: true, | |||
}, | |||
{ | |||
title: '料仓原料', | |||
dataIndex: 'code', | |||
ellipsis: true, | |||
hideInSearch: true, | |||
}, | |||
{ | |||
title: '料仓编号', | |||
dataIndex: 'code', | |||
hideInSearch: true, | |||
ellipsis: true, | |||
}, | |||
{ | |||
title: '剩余', | |||
dataIndex: 'des', | |||
ellipsis: true, | |||
hideInSearch: true, | |||
}, | |||
{ | |||
title: '料仓容积', | |||
dataIndex: 'type', | |||
ellipsis: true, | |||
hideInSearch: true, | |||
}, | |||
{ | |||
title: '操作', | |||
valueType: 'option', | |||
key: 'option', | |||
render: (_, record) => [ | |||
<Button | |||
key="edit" | |||
type="primary" ghost | |||
onClick={async () => { | |||
setIsModalOpen(true); | |||
setModelTitle('编辑信息'); | |||
const copyFormData = JSON.parse(JSON.stringify(record)); | |||
copyFormData.state = copyFormData.state === '0'; | |||
typeForm.setFieldsValue(copyFormData); | |||
}} | |||
> | |||
编辑 | |||
</Button>, | |||
<Popconfirm | |||
key="del" | |||
title="确定要删除此条数据吗?" | |||
onConfirm={() => { | |||
const EnablejsonData: DeviceTypes.Info = { | |||
id: record.id, | |||
name: '', | |||
code: '' | |||
}; | |||
DeviceInfoAPI.Del(EnablejsonData).then((r) => { | |||
if (r.statusCode === 200) { | |||
message.success(r.statusCode === 200 ? '删除成功' : r.message); | |||
actionRef.current?.reload(); | |||
} | |||
}); | |||
}} | |||
onCancel={() => { | |||
message.info('已取消删除'); | |||
}} | |||
okText="确认" | |||
cancelText="关闭" | |||
> | |||
<Button type="primary" danger ghost>删除</Button> | |||
</Popconfirm>, | |||
], | |||
}, | |||
]; | |||
/* | |||
初始化 | |||
*/ | |||
useEffect(() => { | |||
// 下拉列表信息 | |||
const RegionDataList = () => { | |||
}; | |||
RegionDataList(); | |||
}, []); | |||
/* | |||
*表单提交 | |||
*/ | |||
const OnSubmit = async (values: DeviceTypes.Info) => { | |||
if (values.id) { | |||
const response = await DeviceInfoAPI.Update(values); | |||
if (response.statusCode === 200) { | |||
message.success('修改成功'); | |||
actionRef.current?.reload(); | |||
setIsModalOpen(false); | |||
} else { | |||
message.error(JSON.stringify(response.errors) || '修改失败'); | |||
} | |||
} else { | |||
const response = await DeviceInfoAPI.Add(values); | |||
console.log('response', response); | |||
if (response.statusCode === 200) { | |||
message.success('添加成功'); | |||
actionRef.current?.reload(); | |||
setIsModalOpen(false); | |||
} else { | |||
message.error(JSON.stringify(response.errors) || '添加失败'); | |||
} | |||
} | |||
}; | |||
return ( | |||
<> | |||
<ProTable<DeviceTypes.Info> | |||
key="myTable" | |||
columns={columns} | |||
actionRef={actionRef} | |||
cardBordered | |||
request={async (params = {}) => { | |||
const jsonData: DeviceTypes.Page = { | |||
pageIndex: params.current || 1, | |||
pageSize: params.pageSize || 10, | |||
name: params.name || '', | |||
id: '', | |||
code: '' | |||
}; | |||
const response = await DeviceInfoAPI.PagedList(jsonData); | |||
if (response.statusCode === 200) { | |||
return { | |||
data: response.data.items, | |||
success: true, | |||
total: response.data.total, | |||
}; | |||
} else { | |||
return { | |||
data: [], | |||
success: false, | |||
total: 0, | |||
}; | |||
} | |||
}} | |||
rowKey="id" | |||
pagination={{ | |||
pageSize: 10, | |||
}} | |||
dateFormatter="string" | |||
headerTitle="料仓列表" | |||
toolBarRender={() => [ | |||
<Button | |||
key="button" | |||
type="primary" | |||
onClick={() => { | |||
typeForm.resetFields(); | |||
setIsModalOpen(true); | |||
setModelTitle('新增料仓'); | |||
}} | |||
> | |||
新建料仓 | |||
</Button>, | |||
]} | |||
/> | |||
<Modal | |||
key="01" | |||
width={800} | |||
title={<Tag color="#cd201f">{modelTitle}</Tag>} | |||
open={isModalOpen} | |||
onCancel={() => { | |||
setIsModalOpen(false); | |||
}} | |||
footer={[ | |||
<Button | |||
key="back" | |||
onClick={() => { | |||
setIsModalOpen(false); | |||
}} | |||
> | |||
返回 | |||
</Button>, | |||
<Button key="submit" form="myForm" type="primary" htmlType="submit"> | |||
提交 | |||
</Button>, | |||
]} | |||
> | |||
<Form | |||
form={typeForm} | |||
name="basic" | |||
id="myForm" | |||
labelCol={{ span: 4 }} | |||
wrapperCol={{ span: 12 }} | |||
onFinish={OnSubmit} | |||
autoComplete="off" | |||
> | |||
<Form.Item label="id" name="id" hidden> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item | |||
label="料仓名称" | |||
name="name" | |||
rules={[{ required: true, message: '此项为必填项!' }]} | |||
> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item label="料仓原料" name="code" rules={[{ required: true, message: '此项为必填项!' }]} > | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item label="料仓编号" name="code2" rules={[{ required: true, message: '此项为必填项!' }]} > | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item label="剩余" name="des" rules={[{ required: true, message: '此项为必填项!' }]}> | |||
<Input /> | |||
</Form.Item> | |||
<Form.Item label="料仓容积" name="type" rules={[{ required: true, message: '此项为必填项!' }]} > | |||
<Input /> | |||
</Form.Item> | |||
</Form> | |||
</Modal> | |||
</> | |||
); | |||
}; |
@@ -0,0 +1,64 @@ | |||
apiVersion: apps/v1 | |||
kind: Deployment | |||
metadata: | |||
name: pztjapi | |||
namespace: kube-<NAMESPACES> | |||
spec: | |||
selector: | |||
matchLabels: | |||
app: pztjapi | |||
replicas: 1 | |||
template: | |||
metadata: | |||
labels: | |||
app: pztjapi | |||
spec: | |||
containers: | |||
- image: 10.2.1.24:10242/bpa/pztjapi:<BUILD_TAG> | |||
imagePullPolicy: IfNotPresent | |||
name: pztjapi | |||
env: | |||
- name: branch | |||
value: <BRANCH_NAME> | |||
- name: TZ | |||
value: Asia/Shanghai | |||
ports: | |||
- containerPort: 80 | |||
protocol: TCP | |||
volumeMounts: | |||
- mountPath: "/app/appsettings.json" | |||
name: pztjapi-config | |||
readOnly: true | |||
subPath: appsettings | |||
- mountPath: "/etc/localtime" | |||
name: timezone | |||
resources: | |||
requests: | |||
cpu: "100m" | |||
memory: "112Mi" | |||
limits: | |||
cpu: "500m" | |||
memory: "512Mi" | |||
volumes: | |||
- name: pztjapi-config | |||
configMap: | |||
name: pztjapi-config | |||
- name: timezone | |||
hostPath: | |||
path: /usr/share/zoneinfo/Asia/Shanghai | |||
--- | |||
kind: Service | |||
apiVersion: v1 | |||
metadata: | |||
labels: | |||
app: pztjapi | |||
name: pztjapi | |||
namespace: kube-<NAMESPACES> | |||
spec: | |||
type: ClusterIP | |||
ports: | |||
- port: 80 | |||
name: http | |||
selector: | |||
app: pztjapi |
@@ -0,0 +1,55 @@ | |||
apiVersion: apps/v1 | |||
kind: Deployment | |||
metadata: | |||
name: pztjweb | |||
namespace: kube-<NAMESPACES> | |||
spec: | |||
selector: | |||
matchLabels: | |||
app: pztjweb | |||
replicas: 1 | |||
template: | |||
metadata: | |||
labels: | |||
app: pztjweb | |||
spec: | |||
containers: | |||
- image: 10.2.1.24:10242/bpa/pztjweb:<BUILD_TAG> | |||
imagePullPolicy: IfNotPresent | |||
name: pztjweb | |||
env: | |||
- name: branch | |||
value: <BRANCH_NAME> | |||
ports: | |||
- containerPort: 80 | |||
protocol: TCP | |||
volumeMounts: | |||
- mountPath: "/etc/localtime" | |||
name: timezone | |||
resources: | |||
requests: | |||
cpu: "100m" | |||
memory: "112Mi" | |||
limits: | |||
cpu: "500m" | |||
memory: "512Mi" | |||
volumes: | |||
- name: timezone | |||
hostPath: | |||
path: /usr/share/zoneinfo/Asia/Shanghai | |||
--- | |||
kind: Service | |||
apiVersion: v1 | |||
metadata: | |||
labels: | |||
app: pztjweb | |||
name: pztjweb | |||
namespace: kube-<NAMESPACES> | |||
spec: | |||
type: ClusterIP | |||
ports: | |||
- port: 80 | |||
name: http | |||
selector: | |||
app: pztjweb |