123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 |
- <template>
- <div class="data-query">
- <div class="data-query-header">
- <div class="manageTitle">{{ title }}</div>
- <el-form
- ref="formRef"
- :model="formData"
- class="data-query-form"
- :rules="rules"
- @submit.native.prevent
- >
- <div v-if="name === 'freight'" class="form-left">
- <el-form-item prop="startDate">
- <el-date-picker
- v-model="formData.startDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- size="default"
- type="date"
- placeholder="开始日期"
- :prefix-icon="datePreTitle('开始')"
- :clearable="false"
- class="pre-text"
- />
- </el-form-item>
- <el-form-item prop="endDate">
- <el-date-picker
- v-model="formData.endDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- :disabled-date="disabledEndDate"
- size="default"
- type="date"
- placeholder="结束日期"
- :prefix-icon="datePreTitle('结束')"
- :clearable="false"
- class="pre-text"
- />
- </el-form-item>
- </div>
- <div v-if="name === 'waybill'" class="form-left">
- <el-form-item>
- <el-date-picker
- v-model="formData.startDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- size="default"
- type="date"
- placeholder="开始日期"
- :prefix-icon="datePreTitle('开始')"
- class="pre-text"
- />
- </el-form-item>
- <el-form-item>
- <el-date-picker
- v-model="formData.endDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- :disabled-date="disabledEndDate"
- size="default"
- type="date"
- placeholder="结束日期"
- :prefix-icon="datePreTitle('结束')"
- class="pre-text"
- />
- </el-form-item>
- </div>
- <div v-if="name === 'flight'" class="form-left">
- <el-form-item prop="flightDate" style="width: 148px">
- <el-date-picker
- v-model="formData.flightDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- size="default"
- type="date"
- placeholder="请选择航班日期"
- :clearable="false"
- />
- </el-form-item>
- <el-form-item prop="inOrOut" style="width: 108px">
- <el-select v-model="formData.inOrOut" size="default">
- <el-option value="in" label="进港航班" />
- <el-option value="out" label="出港航班" />
- </el-select>
- </el-form-item>
- <el-form-item prop="flightType" style="width: 108px">
- <el-select
- v-model="formData.flightType"
- size="default"
- placeholder="航班类型"
- clearable
- >
- <el-option :value="0" label="货机" />
- <el-option :value="1" label="客机" />
- <el-option :value="2" label="其他" />
- </el-select>
- </el-form-item>
- <el-form-item prop="sAirport" style="width: 108px">
- <el-select
- v-model="formData.sAirport"
- :disabled="formData.inOrOut === 'out'"
- size="default"
- placeholder="始发站"
- filterable
- clearable
- >
- <el-option
- v-for="{ value, label } in airportOptions"
- :key="value"
- :value="value"
- :label="label"
- />
- </el-select>
- </el-form-item>
- <el-form-item prop="eAirport" style="width: 108px">
- <el-select
- v-model="formData.eAirport"
- :disabled="formData.inOrOut === 'in'"
- size="default"
- placeholder="目的站"
- filterable
- clearable
- >
- <el-option
- v-for="{ value, label } in airportOptions"
- :key="value"
- :value="value"
- :label="label"
- />
- </el-select>
- </el-form-item>
- <el-form-item prop="planeType" style="width: 108px">
- <el-select
- v-model="formData.planeType"
- size="default"
- placeholder="属性"
- clearable
- >
- <el-option value="DOM" label="国内" />
- <el-option value="INT" label="国际" />
- </el-select>
- </el-form-item>
- <el-form-item prop="sFlightDate" style="width: 148px">
- <el-date-picker
- v-model="formData.sFlightDate"
- format="YYYY-MM-DD"
- value-format="YYYY-MM-DD"
- size="default"
- type="date"
- placeholder="请选择实飞时间"
- />
- </el-form-item>
- </div>
- <div class="form-right">
- <el-form-item
- v-if="name === 'flight'"
- prop="company"
- style="width: 180px"
- >
- <el-input
- v-model.trim="formData.company"
- size="default"
- placeholder="请输入航司进行搜索"
- :prefix-icon="Search"
- clearable
- @keyup.enter.prevent="dataQuery"
- />
- </el-form-item>
- <el-form-item
- v-if="name === 'waybill'"
- prop="flightNO"
- style="width: 180px"
- >
- <el-input
- v-model.trim="formData.flightNO"
- size="default"
- placeholder="请输入航班号"
- clearable
- />
- </el-form-item>
- <el-form-item
- prop="keyWords"
- :style="name === 'flight' ? { width: '190px' } : {}"
- >
- <el-input
- v-model.trim="formData.keyWords"
- size="default"
- :placeholder="keyWordsPlaceHolder"
- :prefix-icon="Search"
- clearable
- @keyup.enter.prevent="dataQuery"
- />
- </el-form-item>
- </div>
- </el-form>
- <el-button size="default" color="#ac014d" @click="dataQuery"
- >搜索</el-button
- >
- <el-button size="default" plain @click="resetForm">重置</el-button>
- <ColumnSet :table-columns="tableCols" @checked-submit="columnChecked" />
- </div>
- <div
- v-loading="loading"
- element-loading-text="拼命加载中"
- element-loading-background="rgba(0, 0, 0, 0.8)"
- class="data-query-table"
- >
- <SimpleTable
- :header-cell-style="() => ({ background: '#F9FAFC' })"
- ref="tableRef"
- :data="
- tableData.slice((currentPage - 1) * pageSize, currentPage * pageSize)
- "
- :columns="tableCols"
- :cell-class-name="cellClass"
- :column-props="{ formatter }"
- height="calc(100vh - 220px)"
- custom-sequence
- @cell-click="cellClickHandler"
- />
- <el-pagination
- v-if="tableData.length > 0"
- background
- layout="total, prev, pager, next, jumper"
- :total="tableData.length"
- :page-size="pageSize"
- style="position: absolute; right: 19px; bottom: 10px"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- >
- </el-pagination>
- </div>
- </div>
- </template>
- <script setup lang="tsx">
- import { Search } from "@element-plus/icons-vue";
- import ColumnSet from "@/components/ColumnSet/index.vue";
- import SimpleTable from "@/components/SimpleTable/index.vue";
- import { ElMessage, FormInstance } from "element-plus";
- import { parseTime } from "@/utils/validate";
- import { useTable } from "./useTable";
- import { useTableColumnSet } from "@/hooks/useTableColumnSet";
- import { CommonTableFormatter } from "~/common";
- import { Query } from "@/api/webApi";
- const props = defineProps({
- name: {
- type: String,
- required: true,
- },
- title: {
- type: String,
- required: true,
- },
- });
- const tableCols = ref<any[]>([]); //表头数据
- const conditon = ref("");
- const dataContent = ref({});
- const currentPage = ref(1);
- const pageSize = ref(50);
- const today = parseTime(new Date(), "{y}-{m}-{d}") as string;
- const formData = reactive({
- flightDate: today,
- inOrOut: "out",
- flightType: "",
- sAirport: "",
- eAirport: "",
- planeType: "",
- sFlightDate: "",
- company: "",
- startDate: today,
- endDate: today,
- keyWords: "",
- flightNO: "",
- });
- watchEffect(() => {
- if (formData.inOrOut === "in") {
- formData.sAirport = "";
- formData.eAirport = "SZX";
- } else {
- formData.sAirport = "SZX";
- formData.eAirport = "";
- }
- if (!formData.startDate || !formData.endDate) {
- return;
- }
- const start = new Date(formData.startDate).getTime();
- const end = new Date(formData.endDate).getTime();
- if (start > end) {
- ElMessage.warning("开始时间不能晚于结束时间");
- formData.endDate = "";
- }
- if (start <= end - 2 * 24 * 60 * 60 * 1000) {
- ElMessage.warning("间隔不能超过2天");
- formData.endDate = "";
- }
- });
- const disabledEndDate = (endDate: Date) => {
- const start = new Date(formData.startDate + " 00:00:00").getTime();
- const end = endDate.getTime();
- return start > end || start <= end - 2 * 24 * 60 * 60 * 1000;
- };
- const datePreTitle = (title: string) => {
- return <div class="date-pre-title">{title}:</div>;
- };
- const searchTitleMap = {
- flight: "航班号",
- waybill: "运单号",
- freight: "货物编码",
- };
- const keyWordsPlaceHolder = computed(
- () => `请输入${searchTitleMap[props.name] ?? "内容"}进行搜索`
- );
- const airportOptions = ref<{ value: string; label: string }[]>([]);
- const getAirports = async () => {
- try {
- const {
- code,
- returnData: { listValues },
- message,
- } = await Query<{ [x: string]: string }>({
- id: DATACONTENT_ID.airportCode,
- dataContent: [],
- });
- if (Number(code) !== 0) {
- throw new Error(message || "失败");
- }
- airportOptions.value = listValues.map(({ code3 }) => ({
- value: code3,
- label: code3,
- }));
- } catch (error) {
- console.error(error);
- }
- };
- onMounted(() => {
- if (props.name === "flight") {
- getAirports();
- dataQuery();
- }
- });
- const keyWordsValidator = (rule: any, value: any, callback: any) => {
- if (props.name == "waybill") {
- return true;
- }
- const searchTitle = searchTitleMap[props.name] ?? "关键词";
- if (!value) {
- if (["flight"].includes(props.name)) {
- return callback();
- } else {
- return callback(new Error(`请输入${searchTitle}`));
- }
- }
- const regsMap: { [x: string]: RegExp[] } = {
- // flight: [/^[A-Za-z0-9][A-Za-z][0-9]{3,4}$/, /^[0-9]{3,4}$/],
- flight: [/^[0-9]{1,4}$/],
- waybill: [/^[0-9]{8}$/, /^[0-9]{11}$/, /^[0-9]{3}\-[0-9]{8}$/],
- freight: [/^[0-9]{5}$/, /^[0-9]{3}\-[0-9]{8}\-[0-9]{5}$/],
- };
- const regs = regsMap[props.name] ?? [];
- const notMatched = regs.length && regs.every((reg) => !reg.test(value));
- if (notMatched) {
- return callback(new Error(`请输入正确的${searchTitle}`));
- }
- return callback();
- };
- const rules = {
- startDate: [{ required: true, message: "请选择开始日期", trigger: "blur" }],
- endDate: [{ required: true, message: "请选择结束日期", trigger: "blur" }],
- keyWords: [{ validator: keyWordsValidator, trigger: "blur" }],
- flightDate: [{ required: true, message: "请选择航班日期", trigger: "blur" }],
- company: [
- {
- pattern: /^[A-Za-z0-9][A-Za-z0-9]$/,
- message: "请输入正确的航司",
- trigger: "blur",
- },
- ],
- };
- const formRef = ref<FormInstance | null>();
- const dataQuery = () => {
- formRef.value?.validate((valid) => {
- if (valid) {
- tableInit();
- getTableData();
- // load();
- }
- });
- };
- const resetForm = () => {
- formRef.value?.resetFields();
- };
- const loading = ref(false);
- const page = ref(1);
- const noMore = ref(false);
- const { tableColumns, tableData, getTableData } = useTable(
- props.name,
- formData,
- page,
- noMore,
- loading
- );
- const gueryRoles = async () => {
- const { code, returnData } = await Query({
- id: DATACONTENT_ID.allId,
- needPage: ++page.value,
- dataContent: Object.values(dataContent.value),
- });
- conditon.value = returnData.listValues[0].query_col_conditon;
- tableCols.value = [];
- if (conditon.value == null) {
- tableCols.value = tableColumns.value;
- } else {
- conditon.value.split(",").forEach((element) => {
- tableColumns.value.forEach((res) => {
- if (element === res.columnName) {
- tableCols.value.push(res);
- }
- });
- });
- }
- };
- gueryRoles();
- // const load = () => {
- // if (loading.value || noMore.value) {
- // return
- // }
- // page.value++
- // getTableData()
- // }
- const handleSizeChange = (val) => {
- pageSize.value = val;
- };
- const handleCurrentChange = (val) => {
- currentPage.value = val;
- };
- const tableInit = () => {
- page.value = 0;
- noMore.value = false;
- tableData.value = [];
- };
- const { columnChecked } = useTableColumnSet(tableColumns);
- const flightStateMap = {
- CAN: "取消",
- DLY: "延误",
- };
- const flightTypeMap = ["货机", "客机", "其他"];
- const DITypeMap = {
- DOM: "国内",
- INT: "国际",
- };
- const formatter: CommonTableFormatter = (row, column, cellValue, index) => {
- const value = String(cellValue ?? "").trim();
- if (column.property.includes("Time")) {
- return value.replace(/[T|\s]+/, "\n");
- }
- if (column.property === "DIType" && value) {
- return DITypeMap[value] ?? value;
- }
- if (column.property === "flightState") {
- return value ? flightStateMap[value] ?? "正常" : "正常";
- }
- if (column.property === "flightType") {
- return cellValue ? flightTypeMap[cellValue] ?? "其他" : "其他";
- }
- return value;
- };
- const cellClass = ({ row, column, rowIndex, columnIndex }) => {
- const classes: string[] = [];
- switch (props.name) {
- case "flight":
- if (["flightNO"].includes(column.property) && row[column.property]) {
- classes.push("cell-click");
- }
- break;
- case "waybill":
- if (["stockCode"].includes(column.property) && row[column.property]) {
- classes.push("cell-click");
- }
- break;
- case "freight":
- break;
- default:
- break;
- }
- return classes.join(" ");
- };
- const router = useRouter();
- const cellClickHandler = (row, column, cell, event) => {
- switch (props.name) {
- case "flight": {
- switch (column.property) {
- case "flightNO": {
- if (!row.flightAllNO || !row.flightDate) {
- ElMessage.error("航班信息缺失!");
- return;
- }
- if (!["INT", "DOM"].includes(row.DIType)) {
- ElMessage.error("国内/国际无法识别!");
- return;
- }
- const viewName = `${row.DIType === "DOM" ? "" : "International"}${
- row.departureAirport === "SZX" ||
- (!row.departureAirport && row.arriveAirport !== "SZX")
- ? "Departure"
- : "Arrival"
- }Flight`;
- router.push({
- path: `/dataQuery/flightQuery/${viewName}`,
- query: {
- flightNO: row.flightAllNO,
- flightDate: row.flightDate,
- },
- });
- break;
- }
- default:
- break;
- }
- break;
- }
- case "waybill": {
- switch (column.property) {
- case "stockCode": {
- if (
- !row.stockCode ||
- !row.flightDate ||
- !["INT", "DOM"].includes(row.DIType)
- ) {
- ElMessage.error("运单信息缺失!");
- return;
- }
- const viewName = `${row.DIType === "DOM" ? "" : "International"}${
- row.departureAirport === "SZX" ||
- (!row.departureAirport && row.arriveAirport !== "SZX")
- ? "Departure"
- : "Arrival"
- }Waybill`;
- router.push({
- path: `/dataQuery/waybillQuery/${viewName}`,
- query: {
- waybillNO: row.stockCode,
- flightDate: row.flightDate,
- },
- });
- break;
- }
- }
- break;
- }
- case "freight":
- break;
- default:
- break;
- }
- };
- </script>
- <style lang="scss" scoped>
- :deep(.el-pagination.is-background .el-pager li:not(.is-disabled).is-active) {
- background-color: #ac014d !important; //修改默认的背景色
- }
- .data-query {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- &-header {
- width: 100%;
- height: 32px;
- margin: 12px 0;
- display: flex;
- }
- &-form :deep {
- margin-right: 12px;
- flex: 1;
- display: flex;
- justify-content: flex-end;
- .form-left {
- flex: 1;
- display: flex;
- .el-form-item {
- width: 168px;
- margin-right: 8px;
- .el-date-editor.pre-text {
- .el-input__prefix {
- flex-basis: 42px;
- padding-left: 15px;
- .date-pre-title {
- font-style: normal;
- font-size: 14px;
- font-family: Microsoft YaHei;
- color: #303133;
- }
- }
- }
- }
- }
- .form-right {
- display: flex;
- justify-content: flex-end;
- .el-form-item {
- width: 280px;
- &:not(:last-of-type) {
- margin-right: 10px;
- }
- .el-select,
- .el-date-editor {
- width: 100%;
- }
- }
- }
- .el-form-item {
- margin: 0;
- .el-input__inner {
- font-size: 14px;
- font-family: DIN, Microsoft YaHei;
- color: #303133;
- }
- }
- }
- &-table {
- height: 0;
- flex: 1;
- }
- }
- </style>
|