diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 85155ad..b228ae8 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -10,7 +10,9 @@ "Confirm": "Confirm", "Close": "Close", "Save": "Save", + "New": "New", "Edit": "Edit", + "Audit": "Audit", "Delete": "Delete", "Add": "Add", "View": "View", @@ -19,6 +21,23 @@ "Upload": "Upload", "preview": "Preview", "Total": "Total", + "Action": "Action", + "Import": "Import", + "Export": "Export", + "Copy": "Copy", + + "sureCancel": "Are you sure to cancel?", + "sureDelete":"Are you sure to delete?", + "Yes": "Yes", + + "Success": "Success", + "Failed": "Failed", + + "All": "All", + + "Table": { + "Total": "Total {{total}} items" + }, "Login": "Login", "Username": "Username", @@ -46,13 +65,32 @@ "lastThreeMonth": "Last Three Month", "thisYear": "This Year" }, + "weekdays": { + "1": "Monday", + "2": "Tuesday", + "3": "Wednesday", + "4": "Thursday", + "5": "Friday", + "6": "Saturday", + "7": "Sunday" + }, + "weekdaysShort": { + "1": "Mon", + "2": "Tue", + "3": "Wed", + "4": "Thu", + "5": "Fri", + "6": "Sat", + "7": "Sun" + }, "menu": { "Reservation": "Reservation", "Invoice": "Invoice", "Feedback": "Feedback", "Notice": "Notice", "Report": "Report", - "Airticket": "AirTicket" + "Airticket": "AirTicket", + "Products": "Products" }, "Validation": { "Title": "Notification", diff --git a/public/locales/en/products.json b/public/locales/en/products.json new file mode 100644 index 0000000..667c143 --- /dev/null +++ b/public/locales/en/products.json @@ -0,0 +1,111 @@ +{ + "ProductType": "Product Type", + "type": { + "Experience": "Experience", + "Car": "Transport Services", + "Guide": "Guide Services", + "Package": "Package Tour", + "Attractions": "Attractions", + "Meals": "Meals", + "Extras": "Extras", + "UltraService": "Ultra Service" + }, + "EditComponents": { + "info": "Product Information", + "Quotation": "Quotation", + "Extras": "Add-on" + }, + "auditState": { + "New": "New", + "Pending": "Pending", + "Approved": "Approved", + "Rejected": "Rejected", + "Published": "Published" + }, + "auditStateAction": { + "New": "New", + "Pending": "Pending", + "Approved": "Approve", + "Rejected": "Reject", + "Published": "Publish" + }, + "PriceUnit": { + "0": "Person", + "1": "Group", + "title": "Price Unit" + }, + "Status": "Status", + "State": "State", + + "Title": "Title", + "Vendor": "Vendor", + "AuState": "Audit State", + "CreatedBy": "Created By", + "CreateDate": "Create Date", + "AuditedBy": "Audited By", + "AuditDate": "Audit Date", + "OpenHours": "Open Hours", + "Duration": "Duration", + "KM": "KM", + "RecommendsRate": "RecommendsRate", + "OpenWeekdays": "Open Weekdays", + "DisplayToC": "DisplayToC", + "Dept": "Dept", + + "productProject": "Product project", + "Code": "Code", + "City": "City", + "Remarks": "Remarks", + "tourTime": "Tour time", + "recommendationRate": "Recommends rate", + "Name": "Name", + "Description":"Description", + "supplierQuotation": "Supplier quotation", + "addQuotation": "Add quotation", + "bindingProducts": "Binding products", + "addBinding": "Add binding", + + "adultPrice": "Adult price", + "childrenPrice": "Child price", + "currency": "Currency", + "Types": "Type", + "number": "Number", + "validityPeriod":"Validity period", + "operation": "Operation", + "price": "Price", + "weekends":"Weekends", + + "Quotation": "Quotation", + "Offer": "Offer", + + "Unit": "Unit", + "GroupSize": "Group Size", + "UseDates": "Use Dates", + + "Weekdays": "Weekdays", + "OnWeekdays": "On Weekdays: ", + "Unlimited": "Unlimited", + + "UseYear": "Use Year", + + "AgeType": { + "Type": "Age Type", + "Adult": "Adult", + "Child": "Child" + }, + + "save":"save", + "edit":"edit", + "delete":"delete", + "cancel":"cancel", + "sureCancel":"Sure you want to cancel?", + "sureDelete":"Sure you want to delete?", + + "CopyFormMsg": { + "requiredVendor": "Please pick a target vendor", + "requiredTypes": "Please select product types", + "requiredDept": "Please pick a owner department" + }, + + "#": "#" +} diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index 1ffb8ae..dd6e73e 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -10,7 +10,9 @@ "Confirm": "确认", "Close": "关闭", "Save": "保存", + "New": "新增", "Edit": "编辑", + "Audit": "审核", "Delete": "删除", "Add": "添加", "View": "查看", @@ -19,6 +21,23 @@ "Upload": "上传", "preview": "预览", "Total": "总数", + "Action": "操作", + "Import": "导入", + "Export": "导出", + "Copy": "复制", + + "sureCancel": "确定取消?", + "sureDelete":"确定删除?", + "Yes": "是", + + "Success": "成功", + "Failed": "失败", + + "All": "所有", + + "Table": { + "Total": "共 {{total}} 条" + }, "Login": "登录", "Username": "账号", @@ -46,13 +65,32 @@ "lastThreeMonth": "前三个月", "thisYear": "今年" }, + "weekdays": { + "1": "周一", + "2": "周二", + "3": "周三", + "4": "周四", + "5": "周五", + "6": "周六", + "7": "周日" + }, + "weekdaysShort": { + "1": "一", + "2": "二", + "3": "三", + "4": "四", + "5": "五", + "6": "六", + "7": "日" + }, "menu": { "Reservation": "团预订", "Invoice": "账单", "Feedback": "反馈表", "Notice": "通知", "Report": "质量评分", - "Airticket": "机票订票" + "Airticket": "机票订票", + "Products": "产品管理" }, "Validation": { "Title": "温馨提示", diff --git a/public/locales/zh/products.json b/public/locales/zh/products.json new file mode 100644 index 0000000..239af49 --- /dev/null +++ b/public/locales/zh/products.json @@ -0,0 +1,112 @@ +{ + "ProductType": "项目类型", + "type": { + "Experience": "综费", + "Car": "车费", + "Guide": "导游", + "Package": "包价线路", + "Attractions": "景点", + "Meals": "餐费", + "Extras": "附加项目", + "UltraService": "超公里" + }, + "EditComponents": { + "info": "产品信息", + "Quotation": "报价", + "Extras": "附加项目" + }, + "auditState": { + "New": "新增", + "Pending": "待审核", + "Approved": "已通过", + "Rejected": "已拒绝", + "Published": "已发布" + }, + "auditStateAction": { + "New": "新增", + "Pending": "待审核", + "Approved": "审核通过", + "Rejected": "审核拒绝", + "Published": "审核发布" + }, + "PriceUnit": { + "0": "每人", + "1": "每团", + "title": "报价单位" + }, + "Status": "状态", + "State": "状态", + + "Title": "名称", + "Vendor": "供应商", + "AuState": "审核状态", + "CreatedBy": "提交人员", + "CreateDate": "提交时间", + "AuditedBy": "审核人员", + "AuditDate": "审核时间", + + "OpenHours": "游览时间", + "Duration": "游览时长", + "KM": "公里数", + "RecommendsRate": "推荐指数", + "OpenWeekdays": "周开放日", + "DisplayToC": "报价信显示", + "Dept": "小组", + + + "productProject": "产品项目", + "Code": "简码", + "City": "城市", + "Remarks": "备注", + "tourTime": "游览时间", + "recommendationRate": "推荐指数", + "Name":"名称", + "Price":"价格", + "Description":"描述", + "supplierQuotation": "供应商报价", + "addQuotation": "添加报价", + "bindingProducts": "绑定产品", + "addBinding": "添加绑定", + + "adultPrice": "成人价", + "childrenPrice": "儿童价", + "currency": "币种", + "Types": "类型", + "number": "人等", + "validityPeriod":"有效期", + "operation": "操作", + "price": "价格", + + "Quotation": "报价", + "Offer": "报价", + "Unit": "单位", + "GroupSize": "人等", + "UseDates": "使用日期", + + "Weekdays": "周末", + "OnWeekdays": "周: ", + "Unlimited": "不限", + + "UseYear": "年份", + + "AgeType": { + "Type": "人群", + "Adult": "成人", + "Child": "儿童" + }, + + "save":"保存", + "edit":"编辑", + "delete":"删除", + "cancel":"取消", + "sureCancel": "确定取消?", + "sureDelete":"确定删除?", + + "CopyFormMsg": { + "requiredVendor": "请选择目标供应商", + "requiredTypes": "请选择产品类型", + "requiredDept": "请选择所属小组" + }, + + "#": "#" +} diff --git a/src/assets/global.css b/src/assets/global.css index a31e444..cc5d96f 100644 --- a/src/assets/global.css +++ b/src/assets/global.css @@ -1,3 +1,6 @@ @import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities'; +.ant-table-wrapper.border-collapse table { + border-collapse: collapse; +} diff --git a/src/components/AuditStateSelector.jsx b/src/components/AuditStateSelector.jsx new file mode 100644 index 0000000..db4c77d --- /dev/null +++ b/src/components/AuditStateSelector.jsx @@ -0,0 +1,12 @@ +import { Select } from 'antd'; +import { useProductsAuditStates } from '@/hooks/useProductsSets'; + +const AuditStateSelector = ({ ...props }) => { + const states = useProductsAuditStates(); + return ( + <> + + > + ); +}; +export default AuditStateSelector; diff --git a/src/components/BatchImportPrice.jsx b/src/components/BatchImportPrice.jsx new file mode 100644 index 0000000..0404beb --- /dev/null +++ b/src/components/BatchImportPrice.jsx @@ -0,0 +1,243 @@ +import React, { useState } from 'react'; +import { Table, Input, Button, DatePicker, Row, Col, Tag, Select } from 'antd'; + +const { RangePicker } = DatePicker; +const { Option } = Select; +const BatchImportPrice = () => { + const [startDate, setStartDate] = useState(null); + const [endDate, setEndDate] = useState(null); + const [startPeople, setStartPeople] = useState(1); + const [endPeople, setEndPeople] = useState(5); + const [dateRanges, setDateRanges] = useState([]); + const [peopleRanges, setPeopleRanges] = useState([]); + const [tableData, setTableData] = useState([]); + const [currency, setCurrency] = useState('RMB'); // 默认值为 RMB + const [type, setType] = useState('每人'); // 默认值为 每人 + + const handleGenerateTable = () => { + if (dateRanges.length === 0 || peopleRanges.length === 0) return; + + const newData = dateRanges.flatMap(dateRange => { + const { startDate, endDate } = dateRange; + const dates = generateDateRange(startDate, endDate); + const row = { dateRange: `${startDate.format('YYYY-MM-DD')} ~ ${endDate.format('YYYY-MM-DD')}` }; + + peopleRanges.forEach(peopleRangeString => { + const [start, end] = peopleRangeString.split('-').map(Number); + generatePeopleRange(start, end).forEach(person => { + row[`${person}_adultPrice`] = ''; + row[`${person}_childPrice`] = ''; + }); + }); + + dates.forEach(date => { + row[date] = ''; + }); + + return row; + }); + + setTableData(newData); + }; + + const generateDateRange = (start, end) => { + const dates = []; + let currentDate = start.clone(); + + while (currentDate <= end) { + dates.push(currentDate.format('YYYY-MM-DD')); + currentDate = currentDate.add(1, 'day'); + } + + return dates; + }; + + const generatePeopleRange = (start, end) => { + const range = []; + for (let i = start; i <= end; i++) { + range.push(`人等${i}`); + } + return range; + }; + + const handleCellChange = (value, dateRange, peopleRange, type) => { + const newData = [...tableData]; + const rowIndex = newData.findIndex(row => row.dateRange === dateRange); + newData[rowIndex][`${peopleRange}_${type}`] = value; + setTableData(newData); + }; + + const handleAddDateRange = () => { + if (startDate && endDate) { + const newDateRange = { startDate, endDate }; + // 检查是否已经存在相同的日期范围 + const isDateRangeExist = dateRanges.some(range => ( + range.startDate.isSame(startDate, 'day') && range.endDate.isSame(endDate, 'day') + )); + if (!isDateRangeExist) { + setDateRanges([...dateRanges, newDateRange]); + } + } + }; + + const handleAddPeopleRange = () => { + if (startPeople <= endPeople) { + const newPeopleRange = `${startPeople}-${endPeople}`; + // 检查是否已经存在相同的人员范围 + const isPeopleRangeExist = peopleRanges.includes(newPeopleRange); + if (!isPeopleRangeExist) { + setPeopleRanges([...peopleRanges, newPeopleRange]); + } + } + }; + + const handleRemoveTag = (index, type) => { + if (type === 'date') { + setDateRanges(dateRanges.filter((_, i) => i !== index)); + } else { + const removedPeopleRange = peopleRanges[index]; + setPeopleRanges(peopleRanges.filter(range => range !== removedPeopleRange)); + } + setTableData([]); + }; + + + const [adultPrice, setAdultPrice] = useState(''); + const [childPrice, setChildPrice] = useState(''); + + const handleAdultPriceChange = (value, dateRange) => { + const newData = [...tableData]; + const rowIndex = newData.findIndex(row => row.dateRange === dateRange); + newData[rowIndex]['成人价'] = value; + setTableData(newData); + }; + + const handleChildPriceChange = (value, dateRange) => { + const newData = [...tableData]; + const rowIndex = newData.findIndex(row => row.dateRange === dateRange); + newData[rowIndex]['儿童价'] = value; + setTableData(newData); + }; + + const columns = [ + { + title: '日期\\人等', + dataIndex: 'dateRange', + key: 'dateRange', + }, + ...peopleRanges.flatMap(peopleRange => ([ + { + title: peopleRange, + dataIndex: `${peopleRange}_price`, + key: `${peopleRange}_price`, + render: (text, record) => ( +