Merge remote-tracking branch 'origin/Four-Way-Rack' into Four-Way-Rack
| | |
| | | 'commont.enter':'Please enter', |
| | | 'commont.select':'Please select', |
| | | 'common.submit':'Submit', |
| | | 'common.confirm':'Confirm', |
| | | 'common.cancel':'Cancel', |
| | | 'common.reset':'Reset', |
| | | 'common.username':'Username', |
| | |
| | | 'map.settings.bottom': 'Bottom', |
| | | 'map.settings.map.param': 'Map Parameters', |
| | | 'map.settings.config.param': 'Config Parameters', |
| | | 'map.settings.batch.select.shelf': 'Select Shelfs', |
| | | 'map.settings.batch.set.params': 'Set Parameters', |
| | | 'map.settings.batch.result': 'Result', |
| | | 'map.settings.batch.result.title': 'Batch settings successful!', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | '': '', |
| | | 'map.settings.no': 'No.', |
| | |
| | | import React, { useState, useRef, useEffect } from 'react'; |
| | | import { Drawer, Space, Button, Card, Select, InputNumber, Input, Result, Form } from 'antd'; |
| | | import { |
| | | ProCard, |
| | | ProForm, |
| | | ProFormCheckbox, |
| | | ProFormDatePicker, |
| | | ProFormDateRangePicker, |
| | | ProFormSelect, |
| | | ProFormText, |
| | | ProFormTextArea, |
| | | StepsForm, |
| | | } from '@ant-design/pro-components'; |
| | | import { Drawer, Space, Button, Card } from 'antd'; |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import { createStyles } from 'antd-style'; |
| | | import * as Utils from '../utils' |
| | | import ShowJson from '../drawer/showJson'; |
| | | import BatchModify from './modify'; |
| | | |
| | | const useStyles = createStyles(({ token, css }) => { |
| | | return { |
| | | } |
| | | }) |
| | | |
| | | const waitTime = (time = 100) => { |
| | | return new Promise((resolve) => { |
| | | setTimeout(() => { |
| | | resolve(true); |
| | | }, time); |
| | | }); |
| | | }; |
| | | |
| | | const BatchDrawer = (props) => { |
| | | const intl = useIntl(); |
| | | const { styles } = useStyles(); |
| | | const { batchSprites } = props; |
| | | const [form] = Form.useForm(); |
| | | const [currentStep, setCurrentStep] = useState(0); |
| | | |
| | | const resetForm = () => { |
| | | form.resetFields(); |
| | | setCurrentStep(0); |
| | | }; |
| | | const { |
| | | batchSprites, |
| | | model, |
| | | ModelEnum, |
| | | } = props; |
| | | |
| | | useEffect(() => { |
| | | console.log(batchSprites); |
| | | resetForm(); |
| | | }, [props]); |
| | | |
| | | useEffect(() => { |
| | | console.log(currentStep); |
| | | }, [currentStep]); |
| | | |
| | | const handleCancel = () => { |
| | | props.onCancel(); |
| | |
| | | rootStyle={{ position: "absolute" }} |
| | | mask={false} |
| | | width={600} |
| | | placement={'left'} |
| | | style={{ |
| | | opacity: 1 |
| | | }} |
| | |
| | | height: '100%' |
| | | }} |
| | | > |
| | | <StepsForm |
| | | form={form} |
| | | current={currentStep} |
| | | onCurrentChange={setCurrentStep} |
| | | onFinish={async () => { |
| | | await waitTime(1000); |
| | | message.success('提交成功'); |
| | | }} |
| | | formProps={{ |
| | | validateMessages: { |
| | | required: '此项为必填项', |
| | | }, |
| | | variant: 'filled', |
| | | layout: 'horizontal', |
| | | labelCol: { |
| | | span: 4, |
| | | }, |
| | | wrapperCol: { |
| | | span: 20, |
| | | }, |
| | | labelWrap: true |
| | | }} |
| | | submitter={{ |
| | | render: (props, dom) => { |
| | | return props.step === 2 ? [] : dom; |
| | | }, |
| | | }} |
| | | > |
| | | {/************************* first ****************************/} |
| | | <StepsForm.StepForm |
| | | name="base" |
| | | title="选择货架" |
| | | onFinish={() => { |
| | | return true; |
| | | }} |
| | | > |
| | | <ProForm.Item |
| | | > |
| | | {model === ModelEnum.OBSERVER_MODEL && ( |
| | | <> |
| | | <ShowJson |
| | | data={ |
| | | batchSprites?.filter(item => { |
| | | return item.data?.type === Utils.SENSOR_TYPE.SHELF |
| | | }).map(item => { |
| | | batchSprites?.map(item => { |
| | | return item.data?.no; |
| | | }) |
| | | } |
| | | height='500px' |
| | | jsonType={0} |
| | | /> |
| | | </ProForm.Item> |
| | | </StepsForm.StepForm> |
| | | {/************************* second ****************************/} |
| | | <StepsForm.StepForm |
| | | name="checkbox" |
| | | title="设置参数" |
| | | onFinish={(values) => { |
| | | console.log(values); |
| | | return true; |
| | | }} |
| | | > |
| | | <ProForm.Item |
| | | name='shelfType' |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.type', defaultMessage: '类型' })} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <Select |
| | | style={{ width: 120 }} |
| | | options={[ |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.store', defaultMessage: '库位' }), |
| | | value: 0 |
| | | }, |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.track', defaultMessage: '轨道' }), |
| | | value: 3 |
| | | }, |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.diable', defaultMessage: '禁用' }), |
| | | value: 1 |
| | | }, |
| | | ]} |
| | | defaultValue={0} |
| | | </> |
| | | )} |
| | | |
| | | {model === ModelEnum.SETTINGS_MODEL && ( |
| | | <> |
| | | <BatchModify |
| | | batchSprites={batchSprites} |
| | | handleCancel={handleCancel} |
| | | /> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.space', defaultMessage: '间距' })} |
| | | > |
| | | <Space.Compact> |
| | | <ProForm.Item |
| | | name='top' |
| | | noStyle |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact><FormattedMessage id='map.settings.shelf.top' defaultMessage='上' /></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | name='bottom' |
| | | noStyle |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact><FormattedMessage id='map.settings.shelf.bottom' defaultMessage='下' /></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | </Space.Compact> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | label={' '} |
| | | > |
| | | <Space.Compact> |
| | | <ProForm.Item |
| | | name='left' |
| | | noStyle |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact><FormattedMessage id='map.settings.shelf.left' defaultMessage='左' /></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | name='right' |
| | | noStyle |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact><FormattedMessage id='map.settings.shelf.right' defaultMessage='右' /></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | </Space.Compact> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | name='value' |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.value', defaultMessage: '地图值' })} |
| | | > |
| | | <Input |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | </StepsForm.StepForm> |
| | | {/************************* third ****************************/} |
| | | <StepsForm.StepForm |
| | | name="time" |
| | | title="结果" |
| | | submitter={false} |
| | | > |
| | | <Result |
| | | status="success" |
| | | title="Successfully Purchased Cloud Server ECS!" |
| | | subTitle="Order number: 2017182818828182881 Cloud server configuration takes 1-5 minutes, please wait." |
| | | extra={[ |
| | | <Button type="primary" key="console"> |
| | | Go Console |
| | | </Button>, |
| | | ]} |
| | | /> |
| | | </StepsForm.StepForm> |
| | | </StepsForm > |
| | | </> |
| | | )} |
| | | |
| | | </Card > |
| | | </Drawer > |
| | | </> |
New file |
| | |
| | | import React, { useState, useRef, useEffect } from 'react'; |
| | | import { Drawer, Space, Button, Card, Select, InputNumber, Input, Result, Form } from 'antd'; |
| | | import { |
| | | ProForm, |
| | | StepsForm, |
| | | } from '@ant-design/pro-components'; |
| | | import { FormattedMessage, useIntl, useModel } from '@umijs/max'; |
| | | import { createStyles } from 'antd-style'; |
| | | import * as Utils from '../utils' |
| | | import ShowJson from '../drawer/showJson'; |
| | | |
| | | const waitTime = (time = 100) => { |
| | | return new Promise((resolve) => { |
| | | setTimeout(() => { |
| | | resolve(true); |
| | | }, time); |
| | | }); |
| | | }; |
| | | |
| | | const useStyles = createStyles(({ token, css }) => { |
| | | return { |
| | | } |
| | | }) |
| | | |
| | | const BatchModify = (props) => { |
| | | const intl = useIntl(); |
| | | const { styles } = useStyles(); |
| | | const { batchSprites } = props; |
| | | |
| | | const [form] = Form.useForm(); |
| | | const [currentStep, setCurrentStep] = useState(0); |
| | | |
| | | const resetForm = () => { |
| | | form.resetFields(); |
| | | setCurrentStep(0); |
| | | }; |
| | | |
| | | useEffect(() => { |
| | | console.log(batchSprites); |
| | | resetForm(); |
| | | }, [props]); |
| | | |
| | | useEffect(() => { |
| | | console.log(currentStep); |
| | | }, [currentStep]); |
| | | |
| | | return ( |
| | | <> |
| | | <StepsForm |
| | | form={form} |
| | | current={currentStep} |
| | | onCurrentChange={setCurrentStep} |
| | | onFinish={async () => { |
| | | await waitTime(1000); |
| | | message.success('提交成功'); |
| | | }} |
| | | formProps={{ |
| | | variant: 'filled', |
| | | layout: 'horizontal', |
| | | labelCol: { |
| | | span: 4, |
| | | }, |
| | | wrapperCol: { |
| | | span: 20, |
| | | }, |
| | | labelWrap: true |
| | | }} |
| | | submitter={{ |
| | | render: (props, dom) => { |
| | | return props.step === 2 ? [] : dom; |
| | | }, |
| | | }} |
| | | > |
| | | {/************************* first ****************************/} |
| | | <StepsForm.StepForm |
| | | name="base" |
| | | title={intl.formatMessage({ id: 'map.settings.batch.select.shelf', defaultMessage: '选择货架' })} |
| | | onFinish={() => { |
| | | return true; |
| | | }} |
| | | > |
| | | <ProForm.Item |
| | | > |
| | | <ShowJson |
| | | data={ |
| | | batchSprites?.filter(item => { |
| | | return item.data?.type === Utils.SENSOR_TYPE.SHELF |
| | | }).map(item => { |
| | | return item.data?.no; |
| | | }) |
| | | } |
| | | height='500px' |
| | | jsonType={0} |
| | | /> |
| | | </ProForm.Item> |
| | | </StepsForm.StepForm> |
| | | {/************************* second ****************************/} |
| | | <StepsForm.StepForm |
| | | name="checkbox" |
| | | title={intl.formatMessage({ id: 'map.settings.batch.set.params', defaultMessage: '设置参数' })} |
| | | onFinish={(values) => { |
| | | console.log(values); |
| | | return true; |
| | | }} |
| | | > |
| | | <ProForm.Item |
| | | name='shelfType' |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.type', defaultMessage: '类型' })} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | }, |
| | | ]} |
| | | > |
| | | <Select |
| | | style={{ width: 120 }} |
| | | options={[ |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.store', defaultMessage: '库位' }), |
| | | value: 0 |
| | | }, |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.track', defaultMessage: '轨道' }), |
| | | value: 3 |
| | | }, |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.diable', defaultMessage: '禁用' }), |
| | | value: 1 |
| | | }, |
| | | ]} |
| | | defaultValue={0} |
| | | /> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.space', defaultMessage: '间距' })} |
| | | > |
| | | <Space.Compact> |
| | | <ProForm.Item |
| | | name='top' |
| | | noStyle |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact><FormattedMessage id='map.settings.shelf.top' defaultMessage='上' /></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | name='bottom' |
| | | noStyle |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact><FormattedMessage id='map.settings.shelf.bottom' defaultMessage='下' /></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | </Space.Compact> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | label={' '} |
| | | > |
| | | <Space.Compact> |
| | | <ProForm.Item |
| | | name='left' |
| | | noStyle |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact><FormattedMessage id='map.settings.shelf.left' defaultMessage='左' /></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | name='right' |
| | | noStyle |
| | | > |
| | | <InputNumber |
| | | addonBefore={<Space.Compact><FormattedMessage id='map.settings.shelf.right' defaultMessage='右' /></Space.Compact>} |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | </Space.Compact> |
| | | </ProForm.Item> |
| | | <ProForm.Item |
| | | name='value' |
| | | label={intl.formatMessage({ id: 'map.settings.shelf.value', defaultMessage: '地图值' })} |
| | | > |
| | | <Input |
| | | style={{ |
| | | width: '50%', |
| | | }} |
| | | /> |
| | | </ProForm.Item> |
| | | </StepsForm.StepForm> |
| | | {/************************* third ****************************/} |
| | | <StepsForm.StepForm |
| | | name="time" |
| | | title={intl.formatMessage({ id: 'map.settings.batch.result', defaultMessage: '结果' })} |
| | | submitter={false} |
| | | > |
| | | <Result |
| | | status="success" |
| | | title={intl.formatMessage({ id: 'map.settings.batch.result.title', defaultMessage: '批量设置成功' })} |
| | | subTitle="" |
| | | extra={[ |
| | | <Button type="primary" key="console" onClick={props.handleCancel}> |
| | | <FormattedMessage id='common.confirm' defaultMessage='确定' /> |
| | | </Button>, |
| | | ]} |
| | | /> |
| | | </StepsForm.StepForm> |
| | | </StepsForm > |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default BatchModify; |
| | |
| | | // execute where the form was finished |
| | | const confirmSettings = () => { |
| | | if (curSprite && curSprite?.data?.type) { |
| | | curSprite.data = { ...curSprite.data, ...values } |
| | | curSprite.data = { ...curSprite.data, ...values }; |
| | | Utils.showSheflType(curSprite); |
| | | } |
| | | message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '操作成功' })); |
| | | } |
| | |
| | | options={[ |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.store', defaultMessage: '库位' }), |
| | | value: 0 |
| | | value: Utils.SHELF_TYPE.STORE |
| | | }, |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.track', defaultMessage: '轨道' }), |
| | | value: 3 |
| | | value: Utils.SHELF_TYPE.TRACK |
| | | }, |
| | | { |
| | | label: intl.formatMessage({ id: 'map.settings.shelf.diable', defaultMessage: '禁用' }), |
| | | value: 1 |
| | | value: Utils.SHELF_TYPE.DISABLE |
| | | }, |
| | | ]} |
| | | defaultValue={0} |
| | |
| | | break; |
| | | case ModelEnum.MOVABLE_MODEL: |
| | | setModel(ModelEnum.SETTINGS_MODEL); |
| | | // avoid model modify which will clear spriteBySettings |
| | | setTimeout(() => { |
| | | setSpriteBySettings(selectSensor); |
| | | }, 300) |
| | | break; |
| | | case ModelEnum.SETTINGS_MODEL: |
| | | setSpriteBySettings(selectSensor); |
| | |
| | | const prevCurSpriteRef = React.useRef(); |
| | | const hasFloor = true; |
| | | // const [hasFloor, setHasFloor] = React.useState(true); |
| | | const [curFloor, setCurFloor] = React.useState(1); |
| | | const [curFloor, setCurFloor] = React.useState(() => { |
| | | const storedValue = localStorage.getItem('curFloor'); |
| | | return storedValue !== null ? JSON.parse(storedValue) : 1; |
| | | }); |
| | | const [batchSprites, setBatchSprites] = React.useState([]); |
| | | const [batchDrawerVisible, setBatchDrawerVisible] = React.useState(false); |
| | | |
| | |
| | | setDrawerVisible(false); |
| | | setSpriteBySettings(null); |
| | | setSettingsVisible(false); |
| | | setBatchSprites([]); |
| | | setBatchDrawerVisible(false); |
| | | |
| | | switch (model) { |
| | | case MapModel.OBSERVER_MODEL: |
| | |
| | | return; |
| | | } |
| | | switchFloor(curFloor); |
| | | localStorage.setItem('curFloor', JSON.stringify(curFloor)); |
| | | }, [curFloor]); |
| | | |
| | | // watch spriteBySettings |
| | |
| | | }, [spriteBySettings]) |
| | | const prevSpriteBySettings = prevSpriteBySettingsRef.current; |
| | | |
| | | // watch batchSprites |
| | | React.useEffect(() => { |
| | | if (!mapContainer) { |
| | | return; |
| | | } |
| | | if (batchSprites?.length > 0) { |
| | | setBatchDrawerVisible(true) |
| | | } else { |
| | | player.clearSelectedSprites(); |
| | | setBatchDrawerVisible(false) |
| | | } |
| | | }, [batchSprites]) |
| | |
| | | open={batchDrawerVisible} |
| | | batchSprites={batchSprites} |
| | | refCurr={mapRef.current} |
| | | model={model} |
| | | ModelEnum={MapModel} |
| | | onCancel={() => { |
| | | setBatchSprites(null); |
| | | setBatchSprites([]); |
| | | setBatchDrawerVisible(false); |
| | | }} |
| | | /> |
| | |
| | | if (this.mapEvent) { |
| | | this.mapContainer.parent.off('mousedown'); |
| | | this.mapEvent = null; |
| | | if (this.selectedSprites && this.selectedSprites.length > 0) { |
| | | this.selectedSprites.forEach(child => { |
| | | Utils.unMarkSprite(child); |
| | | }) |
| | | } |
| | | // if (this.selectedSprites && this.selectedSprites.length > 0) { |
| | | // this.selectedSprites.forEach(child => { |
| | | // Utils.unMarkSprite(child); |
| | | // }) |
| | | // } |
| | | } |
| | | this.mapEvent = (event) => { |
| | | if (eventType && event.button === 0) { |
| | |
| | | |
| | | this.mapContainer.parent.on('mouseup', (event) => { |
| | | if (isSelecting) { |
| | | if (this.selectedSprites && this.selectedSprites.length > 0) { |
| | | this.selectedSprites.forEach(child => { |
| | | Utils.unMarkSprite(child); |
| | | }) |
| | | } |
| | | this.selectedSprites = []; |
| | | this.clearSelectedSprites(); |
| | | |
| | | // sprite show style which be selected |
| | | this.mapContainer.children.forEach(child => { |
| | |
| | | }); |
| | | } |
| | | |
| | | clearSelectedSprites = () => { |
| | | if (this.selectedSprites && this.selectedSprites.length > 0) { |
| | | this.selectedSprites.forEach(child => { |
| | | Utils.unMarkSprite(child); |
| | | }) |
| | | } |
| | | this.selectedSprites = []; |
| | | } |
| | | |
| | | activateMapPan = () => { |
| | | const mapPanHandle = (event) => { |
| | | if (event.button === 2) { |
| | |
| | | AGV: "AGV", |
| | | }) |
| | | |
| | | export const SHELF_TYPE = Object.freeze({ |
| | | STORE: 0, |
| | | TRACK: 3, |
| | | DISABLE: 1, |
| | | }) |
| | | |
| | | export const getRealPosition = (x, y, mapContainer) => { |
| | | const rect = app.view.getBoundingClientRect(); |
| | | return { |
| | |
| | | copiedSprite.rotation = sprite.rotation; |
| | | copiedSprite.data = deepCopy(sprite.data); |
| | | copiedSprite.data.uuid = generateID(); |
| | | showSheflType(copiedSprite); |
| | | return copiedSprite; |
| | | } |
| | | |
| | |
| | | // dynamical data |
| | | Object.assign(sprite.data, item.property); |
| | | |
| | | showSheflType(sprite); |
| | | // graph |
| | | sprite.position.set(item.positionX, item.positionY); |
| | | sprite.scale.set(item.scaleX, item.scaleY); |
| | | sprite.rotation = rotationParseNum(item.rotation); |
| | | |
| | | // sprite.tint = '#000'; |
| | | mapContainer.addChild(sprite); |
| | | } |
| | | }) |
| | |
| | | onClick: () => { } |
| | | }); |
| | | } |
| | | |
| | | export const showSheflType = (sprite) => { |
| | | let showColor; |
| | | switch (sprite.data.shelfType) { |
| | | case SHELF_TYPE.STORE: |
| | | break; |
| | | case SHELF_TYPE.TRACK: |
| | | showColor = '#faf6e9'; |
| | | break; |
| | | case SHELF_TYPE.DISABLE: |
| | | showColor = '#ffc8c8'; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | if (showColor) { |
| | | sprite.tint = showColor; |
| | | } |
| | | return showColor; |
| | | } |
| | |
| | | port: 9090 |
| | | servlet: |
| | | context-path: /@pom.build.finalName@ |
| | | tomcat: |
| | | max-connections: 30000 |
| | | |
| | | spring: |
| | | application: |
| | |
| | | validation-timeout: 3000 |
| | | connection-test-query: select 1 |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | # url: jdbc:mysql://47.97.1.152:3306/asrs?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai |
| | | # url: jdbc:mysql://47.97.1.152:3306/asrs?useUnicode=trKue&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai |
| | | # username: root |
| | | # password: zy@123 |
| | | url: jdbc:mysql://192.168.4.15:3306/asrs?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai |