Quellcode durchsuchen

Merge branch 'master' of http://git.xt.wenhq.top:8083/wenhongquan/khyznh-ui

# Conflicts:
#	src/views/system/expressStatics/index.vue
liwei19941102 vor 9 Monaten
Ursprung
Commit
0747e4455b

+ 4 - 2
package.json

@@ -47,7 +47,8 @@
     "vue-cropper": "1.0.3",
     "vue-i18n": "9.2.2",
     "vue-router": "4.1.4",
-    "vue-types": "^5.0.3"
+    "vue-types": "^5.0.3",
+    "xlsx": "^0.18.5"
   },
   "devDependencies": {
     "@iconify/json": "^2.2.40",
@@ -87,5 +88,6 @@
     "vitest": "^0.29.7",
     "vue-eslint-parser": "9.1.0",
     "vue-tsc": "0.35.0"
-  }
+  },
+  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
 }

BIN
public/mb.xlsx


+ 70 - 0
src/api/system/upbag/index.ts

@@ -0,0 +1,70 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { BagVO, BagForm, BagQuery } from '@/api/system/upbag/types';
+
+/**
+ * 查询【请填写功能名称】列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listBag = (query?: BagQuery): AxiosPromise<BagVO[]> => {
+  return request({
+    url: '/upsystem/bag/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询【请填写功能名称】详细
+ * @param id
+ */
+export const getBag = (id: string | number): AxiosPromise<BagVO> => {
+  return request({
+    url: '/upsystem/bag/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增【请填写功能名称】
+ * @param data
+ */
+export const addBag = (data: BagForm) => {
+  return request({
+    url: '/upsystem/bag',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改【请填写功能名称】
+ * @param data
+ */
+export const updateBag = (data: BagForm) => {
+  return request({
+    url: '/upsystem/bag',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除【请填写功能名称】
+ * @param id
+ */
+export const delBag = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/upsystem/bag/' + id,
+    method: 'delete'
+  });
+};
+
+export const sysc = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/upsystem/bag/sysc/' + id,
+    method: 'post'
+  });
+};

+ 120 - 0
src/api/system/upbag/types.ts

@@ -0,0 +1,120 @@
+export interface BagVO {
+  /**
+   * 编号
+   */
+  id: string | number;
+
+  /**
+   * 快递柜编号
+   */
+  deviceId: string | number;
+
+  /**
+   * 寄取  1:下行派件入库
+2:下行派件出库
+3:上行揽件入库
+4:上行派件出库
+   */
+  scType: number;
+
+  /**
+   * 寄取时间
+   */
+  scTime: string;
+
+  /**
+   * 快递公司
+   */
+  cpCode: string;
+
+  /**
+   * 运单号
+   */
+  waybillNo: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface BagForm extends BaseEntity {
+  /**
+   * 编号
+   */
+  id?: string | number;
+
+  /**
+   * 快递柜编号
+   */
+  deviceId?: string | number;
+
+  /**
+   * 寄取  1:下行派件入库
+2:下行派件出库
+3:上行揽件入库
+4:上行派件出库
+   */
+  scType?: number;
+
+  /**
+   * 寄取时间
+   */
+  scTime?: string;
+
+  /**
+   * 快递公司
+   */
+  cpCode?: string;
+
+  /**
+   * 运单号
+   */
+  waybillNo?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface BagQuery extends PageQuery {
+
+  /**
+   * 快递柜编号
+   */
+  deviceId?: string | number;
+
+  /**
+   * 寄取  1:下行派件入库
+2:下行派件出库
+3:上行揽件入库
+4:上行派件出库
+   */
+  scType?: number;
+
+  /**
+   * 寄取时间
+   */
+  scTime?: string;
+
+  /**
+   * 快递公司
+   */
+  cpCode?: string;
+
+  /**
+   * 运单号
+   */
+  waybillNo?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 1 - 1
src/components/HomeComponents/lineEcharts.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="lineEchartsClass">
     <div class="titleBg">
-      <div class="titleFont">驿站库存量</div>
+      <div class="titleFont">驿站出入库</div>
     </div>
     <div
       class="divContent"

+ 4 - 4
src/components/HomeComponents/stationPie.vue

@@ -84,7 +84,7 @@
                 "
               >
                 <div class="typeClass">在线设备</div>
-                <div class="countClass" style="color: #22fe31">{{ onlinedevice }}</div>
+                <div class="countClass" style="color: #22fe31">{{ totaldevice }}</div>
               </div>
               <div style="margin-left: 6vw">
                 <img
@@ -306,7 +306,7 @@ const drawEchart = () => {
       // 图形标题(如果想要换行则使用ES6 `` 模板字符串)
       // 例如: `示例
       //   这里的文字会变为第二行(因为会保留格式)
-      text: `${((onlinedevice.value / totaldevice.value) * 100).toFixed(0)}%`,
+      text: `${((totaldevice.value / totaldevice.value) * 100).toFixed(0)}%`,
       subtext: "在线率",
       left: "center", //对齐方式居中
       top: "40%", //距离顶部
@@ -334,8 +334,8 @@ const drawEchart = () => {
           show: false,
         },
         data: [
-          { value: totaldevice.value - onlinedevice.value, name: "在线" },
-          { value: onlinedevice.value, name: "不在线" },
+          { value: totaldevice.value - totaldevice.value, name: "不在线" },
+          { value: totaldevice.value, name: "在线" },
         ],
       },
     ],

+ 1 - 1
src/components/HomeStatics/lineEcharts.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="lineEchartsClass" style="padding-left: 1vw; padding-top: 1.5vh">
-    <div class="title">驿站库存量</div>
+    <div class="title">驿站出入库</div>
     <div ref="linechart" style="width: 100%; height: 90%"></div>
   </div>
 </template>

+ 4 - 4
src/components/HomeStatics/stationPie.vue

@@ -38,7 +38,7 @@
           "
         >
           <div class="stationkeyClass">在线设备</div>
-          <div class="stationvalueClass">{{ onlinedevice }}</div>
+          <div class="stationvalueClass">{{ totaldevice }}</div>
           <div class="stationunitClass">台</div>
         </div>
         <img class="imageDiv" src="@/assets/images/home/Bg(7).png" />
@@ -119,7 +119,7 @@ const drawEchart = () => {
       // 图形标题(如果想要换行则使用ES6 `` 模板字符串)
       // 例如: `示例
       //   这里的文字会变为第二行(因为会保留格式)
-      text: `${((onlinedevice.value / totaldevice.value) * 100).toFixed(0)}%`,
+      text: `${((totaldevice.value / totaldevice.value) * 100).toFixed(0)}%`,
       subtext: "在线率",
       left: "center", //对齐方式居中
       top: "35%", //距离顶部
@@ -147,8 +147,8 @@ const drawEchart = () => {
           show: false,
         },
         data: [
-          { value: totaldevice.value - onlinedevice.value, name: "在线" },
-          { value: onlinedevice.value, name: "不在线" },
+          { value: totaldevice.value - totaldevice.value, name: "不在线" },
+          { value: totaldevice.value, name: "在线" },
         ],
       },
     ],

+ 2 - 2
src/views/login.vue

@@ -2,7 +2,7 @@
   <div class="login">
     <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
       <h3 class="title">农村客运信息化管理系统</h3>
-      <el-form-item prop="tenantId" v-if="tenantEnabled">
+      <el-form-item prop="tenantId" v-if="false">
         <el-select v-model="loginForm.tenantId" filterable placeholder="请选择/输入公司名称" style="width: 100%">
           <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"></el-option>
           <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
@@ -53,7 +53,7 @@
     </el-form>
     <!--  底部  -->
     <div class="el-login-footer">
-      <span>Copyright © 2018-2024 crj All Rights Reserved.</span>
+      <span>Copyright © 2023-2025 福建瑞华数字技术有限公司 All Rights Reserved. 闽ICP备2023005786号</span>
     </div>
   </div>
 </template>

+ 350 - 243
src/views/system/bag/index.vue

@@ -1,21 +1,55 @@
 <template>
   <div class="p-2">
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
-      :leave-active-class="proxy?.animate.searchAnimate.leave">
+    <transition
+      :enter-active-class="proxy?.animate.searchAnimate.enter"
+      :leave-active-class="proxy?.animate.searchAnimate.leave"
+    >
       <div class="search" v-show="showSearch">
-        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+        <el-form
+          :model="queryParams"
+          ref="queryFormRef"
+          :inline="true"
+          label-width="68px"
+        >
           <el-form-item label="快递单号" prop="bagNumber">
-            <el-input v-model="queryParams.bagNumber" placeholder="请输入快递单号" clearable style="width: 240px"
-              @keyup.enter="handleQuery" />
+            <el-input
+              v-model="queryParams.bagNumber"
+              placeholder="请输入快递单号"
+              clearable
+              style="width: 240px"
+              @keyup.enter="handleQuery"
+            />
           </el-form-item>
           <el-form-item label="出库状态" prop="bagOutTime">
-            <el-select v-model="queryParams.bagStatus" placeholder="出库状态" clearable size="default" style="width: 240px">
-              <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+            <el-select
+              v-model="queryParams.bagStatus"
+              placeholder="出库状态"
+              clearable
+              size="default"
+              style="width: 240px"
+            >
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
             </el-select>
           </el-form-item>
           <el-form-item label="所在站点" prop="bagSite">
-            <el-select v-model="queryParams.bagSite" placeholder="所在站点" clearable size="default" style="width: 240px">
-              <el-option v-for="item in siteList" :key="item.id" :label="item.siteName" :value="item.id" />
+            <el-select
+              v-model="queryParams.bagSite"
+              placeholder="所在站点"
+              clearable
+              size="default"
+              style="width: 240px"
+            >
+              <el-option
+                v-for="item in siteList"
+                :key="item.id"
+                :label="item.siteName"
+                :value="item.id"
+              />
             </el-select>
           </el-form-item>
           <el-form-item>
@@ -30,26 +64,59 @@
       <template #header>
         <el-row :gutter="10" class="mb8">
           <el-col :span="1.5">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd"
-              v-hasPermi="['system:bag:add']">新增</el-button>
+            <el-button
+              type="primary"
+              plain
+              icon="Plus"
+              @click="handleAdd"
+              v-hasPermi="['system:bag:add']"
+              >新增</el-button
+            >
           </el-col>
           <el-col :span="1.5">
-            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
-              v-hasPermi="['system:bag:edit']">修改</el-button>
+            <el-button
+              type="success"
+              plain
+              icon="Edit"
+              :disabled="single"
+              @click="handleUpdate()"
+              v-hasPermi="['system:bag:edit']"
+              >修改</el-button
+            >
           </el-col>
           <el-col :span="1.5">
-            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
-              v-hasPermi="['system:bag:remove']">删除</el-button>
+            <el-button
+              type="danger"
+              plain
+              icon="Delete"
+              :disabled="multiple"
+              @click="handleDelete()"
+              v-hasPermi="['system:bag:remove']"
+              >删除</el-button
+            >
           </el-col>
           <el-col :span="1.5">
-            <el-button type="warning" plain icon="Download" @click="handleExport"
-              v-hasPermi="['system:bag:export']">导出</el-button>
+            <el-button
+              type="warning"
+              plain
+              icon="Download"
+              @click="handleExport"
+              v-hasPermi="['system:bag:export']"
+              >导出</el-button
+            >
           </el-col>
-          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+          <right-toolbar
+            v-model:showSearch="showSearch"
+            @queryTable="getList"
+          ></right-toolbar>
         </el-row>
       </template>
 
-      <el-table v-loading="loading" :data="bagList" @selection-change="handleSelectionChange">
+      <el-table
+        v-loading="loading"
+        :data="bagList"
+        @selection-change="handleSelectionChange"
+      >
         <el-table-column type="selection" width="55" align="center" />
         <el-table-column label="id" align="center" prop="id" v-if="true" />
         <el-table-column label="快递公司" align="center" prop="bagCompany" />
@@ -68,34 +135,58 @@
         </el-table-column>
         <el-table-column label="入库时间" align="center" prop="createdAt" width="180">
           <template #default="scope">
-            <span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d}') }}</span>
+            <span>{{ parseTime(scope.row.createdAt, "{y}-{m}-{d}") }}</span>
           </template>
         </el-table-column>
         <el-table-column label="出库时间" align="center" prop="bagOutTime" width="180">
           <template #default="scope">
-            <span>{{ parseTime(scope.row.bagOutTime, '{y}-{m}-{d}') }}</span>
+            <span>{{ parseTime(scope.row.bagOutTime, "{y}-{m}-{d}") }}</span>
           </template>
         </el-table-column>
         <el-table-column label="异常原因" align="center" prop="bagReason" />
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <el-table-column
+          label="操作"
+          align="center"
+          class-name="small-padding fixed-width"
+        >
           <template #default="scope">
             <el-tooltip content="修改" placement="top">
-              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
-                v-hasPermi="['system:bag:edit']"></el-button>
+              <el-button
+                link
+                type="primary"
+                icon="Edit"
+                @click="handleUpdate(scope.row)"
+                v-hasPermi="['system:bag:edit']"
+              ></el-button>
             </el-tooltip>
             <el-tooltip content="删除" placement="top">
-              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
-                v-hasPermi="['system:bag:remove']"></el-button>
+              <el-button
+                link
+                type="primary"
+                icon="Delete"
+                @click="handleDelete(scope.row)"
+                v-hasPermi="['system:bag:remove']"
+              ></el-button>
             </el-tooltip>
           </template>
         </el-table-column>
       </el-table>
 
-      <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum"
-        v-model:limit="queryParams.pageSize" @pagination="getList" />
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+      />
     </el-card>
     <!-- 添加或修改【请填写功能名称】对话框 -->
-    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+    <el-dialog
+      :title="dialog.title"
+      v-model="dialog.visible"
+      width="500px"
+      append-to-body
+    >
       <el-form ref="bagFormRef" :model="form" :rules="rules" label-width="80px">
         <el-form-item label="快递公司" prop="bagCompany">
           <el-input v-model="form.bagCompany" placeholder="请输入快递公司" />
@@ -104,8 +195,13 @@
           <el-input v-model="form.bagNumber" placeholder="请输入快递单号" />
         </el-form-item>
         <el-form-item label="出库时间" prop="bagOutTime">
-          <el-date-picker clearable v-model="form.bagOutTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
-            placeholder="请选择出库时间">
+          <el-date-picker
+            clearable
+            v-model="form.bagOutTime"
+            type="datetime"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            placeholder="请选择出库时间"
+          >
           </el-date-picker>
         </el-form-item>
         <el-form-item label="货架号" prop="bagLocal">
@@ -115,30 +211,50 @@
           <el-input v-model="form.bagLocal2" placeholder="请输入层号" />
         </el-form-item>
         <el-form-item label="入库时间,停用" prop="bagInTime">
-          <el-date-picker clearable v-model="form.bagInTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
-            placeholder="请选择入库时间,停用">
+          <el-date-picker
+            clearable
+            v-model="form.bagInTime"
+            type="datetime"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            placeholder="请选择入库时间,停用"
+          >
           </el-date-picker>
         </el-form-item>
         <el-form-item label="异常原因,如退件、损坏等" prop="bagReason">
-          <el-input v-model="form.bagReason" placeholder="请输入异常原因,如退件、损坏等" />
+          <el-input
+            v-model="form.bagReason"
+            placeholder="请输入异常原因,如退件、损坏等"
+          />
         </el-form-item>
         <el-form-item label="所在站点" prop="bagSite">
           <el-input v-model="form.bagSite" placeholder="请输入所在站点" />
         </el-form-item>
         <el-form-item label="修改时间" prop="updatedAt">
-          <el-date-picker clearable v-model="form.updatedAt" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
-            placeholder="请选择修改时间">
+          <el-date-picker
+            clearable
+            v-model="form.updatedAt"
+            type="datetime"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            placeholder="请选择修改时间"
+          >
           </el-date-picker>
         </el-form-item>
         <el-form-item label="创建时间,入库时间" prop="createdAt">
-          <el-date-picker clearable v-model="form.createdAt" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
-            placeholder="请选择创建时间,入库时间">
+          <el-date-picker
+            clearable
+            v-model="form.createdAt"
+            type="datetime"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            placeholder="请选择创建时间,入库时间"
+          >
           </el-date-picker>
         </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm"
+            >确 定</el-button
+          >
           <el-button @click="cancel">取 消</el-button>
         </div>
       </template>
@@ -147,32 +263,49 @@
 </template>
 
 <script setup name="Bag" lang="ts">
-  import { listBag, getBag, delBag, addBag, updateBag } from '@/api/system/bag';
-  import { BagVO, BagQuery, BagForm } from '@/api/system/bag/types';
-  import { listSite, getSite, delSite, addSite, updateSite } from '@/api/system/site';
-  import { SiteVO, SiteQuery, SiteForm } from '@/api/system/site/types';
+import { listBag, getBag, delBag, addBag, updateBag } from "@/api/system/bag";
+import { BagVO, BagQuery, BagForm } from "@/api/system/bag/types";
+import { listSite, getSite, delSite, addSite, updateSite } from "@/api/system/site";
+import { SiteVO, SiteQuery, SiteForm } from "@/api/system/site/types";
 
-  const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
-  const bagList = ref < BagVO[] > ([]);
-  const buttonLoading = ref(false);
-  const loading = ref(true);
-  const showSearch = ref(true);
-  const ids = ref < Array < string | number >> ([]);
-  const single = ref(true);
-  const multiple = ref(true);
-  const total = ref(0);
+const bagList = ref<BagVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
 
-  const queryFormRef = ref < ElFormInstance > ();
-  const bagFormRef = ref < ElFormInstance > ();
+const queryFormRef = ref<ElFormInstance>();
+const bagFormRef = ref<ElFormInstance>();
 
-  const dialog = reactive < DialogOption > ({
-    visible: false,
-    title: ''
-  });
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: "",
+});
 
-  const initFormData: BagForm = {
-    id: undefined,
+const initFormData: BagForm = {
+  id: undefined,
+  bagCompany: undefined,
+  bagNumber: undefined,
+  bagStatus: undefined,
+  bagOutTime: undefined,
+  bagLocal: undefined,
+  bagLocal2: undefined,
+  bagInTime: undefined,
+  bagReason: undefined,
+  bagSite: undefined,
+  updatedAt: undefined,
+  createdAt: undefined,
+};
+const data = reactive<PageData<BagForm, BagQuery>>({
+  form: { ...initFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
     bagCompany: undefined,
     bagNumber: undefined,
     bagStatus: undefined,
@@ -183,208 +316,182 @@
     bagReason: undefined,
     bagSite: undefined,
     updatedAt: undefined,
-    createdAt: undefined
-  }
-  const data = reactive < PageData < BagForm, BagQuery>> ({
-    form: { ...initFormData },
-    queryParams: {
-      pageNum: 1,
-      pageSize: 10,
-      bagCompany: undefined,
-      bagNumber: undefined,
-      bagStatus: undefined,
-      bagOutTime: undefined,
-      bagLocal: undefined,
-      bagLocal2: undefined,
-      bagInTime: undefined,
-      bagReason: undefined,
-      bagSite: undefined,
-      updatedAt: undefined,
-      createdAt: undefined,
-      params: {
-      }
-    },
-    rules: {
-      id: [
-        { required: true, message: "id不能为空", trigger: "blur" }
-      ],
-      bagCompany: [
-        { required: true, message: "快递公司不能为空", trigger: "blur" }
-      ],
-      bagNumber: [
-        { required: true, message: "快递单号不能为空", trigger: "blur" }
-      ],
-      bagStatus: [
-        { required: true, message: "出库状态,待取件0,出库1,异常2,异常已处理3不能为空", trigger: "change" }
-      ],
-      bagOutTime: [
-        { required: true, message: "出库时间不能为空", trigger: "blur" }
-      ],
-      bagLocal: [
-        { required: true, message: "货架号不能为空", trigger: "blur" }
-      ],
-      bagLocal2: [
-        { required: true, message: "层号不能为空", trigger: "blur" }
-      ],
-      bagInTime: [
-        { required: true, message: "入库时间,停用不能为空", trigger: "blur" }
-      ],
-      bagReason: [
-        { required: true, message: "异常原因,如退件、损坏等不能为空", trigger: "blur" }
-      ],
-      bagSite: [
-        { required: true, message: "所在站点不能为空", trigger: "blur" }
-      ],
-      updatedAt: [
-        { required: true, message: "修改时间不能为空", trigger: "blur" }
-      ],
-      createdAt: [
-        { required: true, message: "创建时间,入库时间不能为空", trigger: "blur" }
-      ]
-    }
-  });
+    createdAt: undefined,
+    params: {},
+  },
+  rules: {
+    id: [{ required: true, message: "id不能为空", trigger: "blur" }],
+    bagCompany: [{ required: true, message: "快递公司不能为空", trigger: "blur" }],
+    bagNumber: [{ required: true, message: "快递单号不能为空", trigger: "blur" }],
+    bagStatus: [
+      {
+        required: true,
+        message: "出库状态,待取件0,出库1,异常2,异常已处理3不能为空",
+        trigger: "change",
+      },
+    ],
+    bagOutTime: [{ required: true, message: "出库时间不能为空", trigger: "blur" }],
+    bagLocal: [{ required: true, message: "货架号不能为空", trigger: "blur" }],
+    bagLocal2: [{ required: true, message: "层号不能为空", trigger: "blur" }],
+    bagInTime: [{ required: true, message: "入库时间,停用不能为空", trigger: "blur" }],
+    bagReason: [
+      { required: true, message: "异常原因,如退件、损坏等不能为空", trigger: "blur" },
+    ],
+    bagSite: [{ required: true, message: "所在站点不能为空", trigger: "blur" }],
+    updatedAt: [{ required: true, message: "修改时间不能为空", trigger: "blur" }],
+    createdAt: [
+      { required: true, message: "创建时间,入库时间不能为空", trigger: "blur" },
+    ],
+  },
+});
 
-  const { queryParams, form, rules } = toRefs(data);
+const { queryParams, form, rules } = toRefs(data);
 
-  const options = [
-    {
-      value: '0',
-      label: '待入库',
-    },
-    {
-      value: '1',
-      label: '出库',
-    },
-    {
-      value: '2',
-      label: '异常',
-    },
-    {
-      value: '3',
-      label: '异常已处理',
-    }
-  ]
+const options = [
+  {
+    value: "0",
+    label: "待取件",
+  },
+  {
+    value: "1",
+    label: "出库",
+  },
+  {
+    value: "2",
+    label: "异常",
+  },
+  {
+    value: "3",
+    label: "异常已处理",
+  },
+];
 
-  const siteList = ref([])
+const siteList = ref([]);
 
-  /** 查询【请填写功能名称】列表 */
-  const getList = async () => {
-    loading.value = true;
-    const res = await listBag(queryParams.value);
-    bagList.value = res.rows;
-    total.value = res.total;
-    loading.value = false;
-  }
+/** 查询【请填写功能名称】列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listBag(queryParams.value);
+  bagList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+};
 
-  /** 取消按钮 */
-  const cancel = () => {
-    reset();
-    dialog.visible = false;
-  }
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+};
 
-  const getStatus = (status) => {
-    if (status == 0) {
-      return "待取件"
-    } else if (status == 1) {
-      return "已出库"
-    } else if (status == 2) {
-      return "异常"
-    } else {
-      return "异常已处理"
-    }
+const getStatus = (status) => {
+  if (status == 0) {
+    return "待取件";
+  } else if (status == 1) {
+    return "已出库";
+  } else if (status == 2) {
+    return "异常";
+  } else {
+    return "异常已处理";
   }
+};
 
-  const getSiteData = () => {
-    listSite({ pageSize: 1000 }).then(res => {
-      siteList.value = res.rows
-    })
-  }
+const getSiteData = () => {
+  listSite({ pageSize: 1000 }).then((res) => {
+    siteList.value = res.rows;
+  });
+};
 
-  const getSiteName = (id) => {
-    for (var index in siteList.value) {
-      if (siteList.value[index].id == id) {
-        return siteList.value[index].siteName
-      }
+const getSiteName = (id) => {
+  for (var index in siteList.value) {
+    if (siteList.value[index].id == id) {
+      return siteList.value[index].siteName;
     }
   }
+};
 
-  /** 表单重置 */
-  const reset = () => {
-    form.value = { ...initFormData };
-    bagFormRef.value?.resetFields();
-  }
+/** 表单重置 */
+const reset = () => {
+  form.value = { ...initFormData };
+  bagFormRef.value?.resetFields();
+};
 
-  /** 搜索按钮操作 */
-  const handleQuery = () => {
-    queryParams.value.pageNum = 1;
-    getList();
-  }
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+};
 
-  /** 重置按钮操作 */
-  const resetQuery = () => {
-    queryFormRef.value?.resetFields();
-    handleQuery();
-  }
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+};
 
-  /** 多选框选中数据 */
-  const handleSelectionChange = (selection: BagVO[]) => {
-    ids.value = selection.map(item => item.id);
-    single.value = selection.length != 1;
-    multiple.value = !selection.length;
-  }
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: BagVO[]) => {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+};
 
-  /** 新增按钮操作 */
-  const handleAdd = () => {
-    reset();
-    dialog.visible = true;
-    dialog.title = "添加【请填写功能名称】";
-  }
+/** 新增按钮操作 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "添加【请填写功能名称】";
+};
 
-  /** 修改按钮操作 */
-  const handleUpdate = async (row?: BagVO) => {
-    reset();
-    const _id = row?.id || ids.value[0]
-    const res = await getBag(_id);
-    Object.assign(form.value, res.data);
-    dialog.visible = true;
-    dialog.title = "修改【请填写功能名称】";
-  }
+/** 修改按钮操作 */
+const handleUpdate = async (row?: BagVO) => {
+  reset();
+  const _id = row?.id || ids.value[0];
+  const res = await getBag(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改【请填写功能名称】";
+};
 
-  /** 提交按钮 */
-  const submitForm = () => {
-    bagFormRef.value?.validate(async (valid: boolean) => {
-      if (valid) {
-        buttonLoading.value = true;
-        if (form.value.id) {
-          await updateBag(form.value).finally(() => buttonLoading.value = false);
-        } else {
-          await addBag(form.value).finally(() => buttonLoading.value = false);
-        }
-        proxy?.$modal.msgSuccess("修改成功");
-        dialog.visible = false;
-        await getList();
+/** 提交按钮 */
+const submitForm = () => {
+  bagFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateBag(form.value).finally(() => (buttonLoading.value = false));
+      } else {
+        await addBag(form.value).finally(() => (buttonLoading.value = false));
       }
-    });
-  }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+};
 
-  /** 删除按钮操作 */
-  const handleDelete = async (row?: BagVO) => {
-    const _ids = row?.id || ids.value;
-    await proxy?.$modal.confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
-    await delBag(_ids);
-    proxy?.$modal.msgSuccess("删除成功");
-    await getList();
-  }
+/** 删除按钮操作 */
+const handleDelete = async (row?: BagVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal
+    .confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项?')
+    .finally(() => (loading.value = false));
+  await delBag(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+};
 
-  /** 导出按钮操作 */
-  const handleExport = () => {
-    proxy?.download('system/bag/export', {
-      ...queryParams.value
-    }, `bag_${new Date().getTime()}.xlsx`)
-  }
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download(
+    "system/bag/export",
+    {
+      ...queryParams.value,
+    },
+    `bag_${new Date().getTime()}.xlsx`
+  );
+};
 
-  onMounted(() => {
-    getSiteData();
-    getList();
-  });
-</script>
+onMounted(() => {
+  getSiteData();
+  getList();
+});
+</script>

+ 235 - 211
src/views/system/expressStatics/index.vue

@@ -1,14 +1,39 @@
 <template>
   <div class="p-2">
-    <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
-      :leave-active-class="proxy?.animate.searchAnimate.leave">
+    <transition
+      :enter-active-class="proxy?.animate.searchAnimate.enter"
+      :leave-active-class="proxy?.animate.searchAnimate.leave"
+    >
       <div class="search" v-show="showSearch">
-        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+        <el-form
+          :model="queryParams"
+          ref="queryFormRef"
+          :inline="true"
+          label-width="68px"
+        >
           <el-form-item label="名称" prop="userId">
-            <el-select v-model="queryParams.userId" clearable placeholder="请选择快递员" style="width: 240px">
-              <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
+            <el-select
+              v-model="queryParams.userId"
+              clearable
+              placeholder="请选择快递员"
+              style="width: 240px"
+            >
+              <el-option
+                v-for="item in userList"
+                :key="item.userId"
+                :label="item.nickName"
+                :value="item.userId"
+              />
             </el-select>
           </el-form-item>
+          <el-form-item label="月份" prop="userId">
+            <el-date-picker
+              v-model="queryParams.params.ctime"
+              type="month"
+              placeholder="选择月份"
+            />
+          </el-form-item>
+
           <el-form-item>
             <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
             <el-button icon="Refresh" @click="resetQuery">重置</el-button>
@@ -18,29 +43,11 @@
     </transition>
 
     <el-card shadow="never">
-      <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="1.5">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd"
-              v-hasPermi="['system:expressStatics:add']">新增</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
-              v-hasPermi="['system:expressStatics:edit']">修改</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
-              v-hasPermi="['system:expressStatics:remove']">删除</el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="warning" plain icon="Download" @click="handleExport"
-              v-hasPermi="['system:expressStatics:export']">导出</el-button>
-          </el-col>
-          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-        </el-row>
-      </template>
-
-      <el-table v-loading="loading" :data="expressStaticsList" @selection-change="handleSelectionChange">
+      <el-table
+        v-loading="loading"
+        :data="expressStaticsList"
+        @selection-change="handleSelectionChange"
+      >
         <el-table-column type="selection" width="55" align="center" />
         <!-- <el-table-column label="" align="center" prop="id" v-if="true" /> -->
         <el-table-column label="用户" align="center" prop="userId">
@@ -48,18 +55,13 @@
             <span>{{ getUserName(scope.row) }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="手机号" align="center" prop="userId">
-          <template #default="scope">
-            <span>{{ getPhone(scope.row) }}</span>
-          </template>
-        </el-table-column>
         <el-table-column label="月份" align="center" prop="month" />
         <el-table-column label="投递数" align="center" prop="data">
           <template #default="scope">
             <span>{{ getData(scope.row) }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
           <template #default="scope">
             <el-tooltip content="修改" placement="top">
               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
@@ -70,15 +72,30 @@
                 v-hasPermi="['system:expressStatics:remove']"></el-button>
             </el-tooltip>
           </template>
-        </el-table-column>
+        </el-table-column> -->
       </el-table>
 
-      <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum"
-        v-model:limit="queryParams.pageSize" @pagination="getList" />
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+      />
     </el-card>
     <!-- 添加或修改【请填写功能名称】对话框 -->
-    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
-      <el-form ref="expressStaticsFormRef" :model="form" :rules="rules" label-width="80px">
+    <el-dialog
+      :title="dialog.title"
+      v-model="dialog.visible"
+      width="500px"
+      append-to-body
+    >
+      <el-form
+        ref="expressStaticsFormRef"
+        :model="form"
+        :rules="rules"
+        label-width="80px"
+      >
         <el-form-item label="" prop="userId">
           <el-input v-model="form.userId" placeholder="请输入" />
         </el-form-item>
@@ -91,7 +108,9 @@
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm"
+            >确 定</el-button
+          >
           <el-button @click="cancel">取 消</el-button>
         </div>
       </template>
@@ -100,206 +119,211 @@
 </template>
 
 <script setup name="ExpressStatics" lang="ts">
-  import { listExpressStatics, getExpressStatics, delExpressStatics, addExpressStatics, updateExpressStatics } from '@/api/system/expressStatics';
-  import { ExpressStaticsVO, ExpressStaticsQuery, ExpressStaticsForm } from '@/api/system/expressStatics/types';
-  import api from "@/api/system/user"
-  import { UserForm, UserQuery, UserVO } from '@/api/system/user/types';
+import {
+  listExpressStatics,
+  getExpressStatics,
+  delExpressStatics,
+  addExpressStatics,
+  updateExpressStatics,
+} from "@/api/system/expressStatics";
+import {
+  ExpressStaticsVO,
+  ExpressStaticsQuery,
+  ExpressStaticsForm,
+} from "@/api/system/expressStatics/types";
+import api from "@/api/system/user";
+import { UserForm, UserQuery, UserVO } from "@/api/system/user/types";
+import { deepClone } from "@/utils";
+import moment from "moment";
 
-  const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
-  const expressStaticsList = ref < ExpressStaticsVO[] > ([]);
-  const buttonLoading = ref(false);
-  const loading = ref(true);
-  const showSearch = ref(true);
-  const ids = ref < Array < string | number >> ([]);
-  const single = ref(true);
-  const multiple = ref(true);
-  const total = ref(0);
-  const userList = ref([]);
+const expressStaticsList = ref<ExpressStaticsVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const userList = ref([]);
 
-  const queryFormRef = ref < ElFormInstance > ();
-  const expressStaticsFormRef = ref < ElFormInstance > ();
+const queryFormRef = ref<ElFormInstance>();
+const expressStaticsFormRef = ref<ElFormInstance>();
 
-  const dialog = reactive < DialogOption > ({
-    visible: false,
-    title: ''
-  });
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: "",
+});
 
-  const initFormData: ExpressStaticsForm = {
-    id: undefined,
+const initFormData: ExpressStaticsForm = {
+  id: undefined,
+  userId: undefined,
+  month: undefined,
+  data: undefined,
+};
+const data = reactive<PageData<ExpressStaticsForm, ExpressStaticsQuery>>({
+  form: { ...initFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
     userId: undefined,
     month: undefined,
     data: undefined,
-  }
-  const data = reactive < PageData < ExpressStaticsForm, ExpressStaticsQuery>> ({
-    form: { ...initFormData },
-    queryParams: {
-      pageNum: 1,
-      pageSize: 10,
-      userId: undefined,
-      month: undefined,
-      data: undefined,
-      params: {
-      }
+    params: {
+      ctime: moment().format("YYYY-MM"),
     },
-    userParams: {
-      pageNum: 1,
-      pageSize: 1000,
-      userName: '',
-      phonenumber: '',
-      status: '',
-      deptId: '',
-      params: {
-        roleNames: '司机'
-      }
+  },
+  userParams: {
+    pageNum: 1,
+    pageSize: 1000,
+    userName: "",
+    phonenumber: "",
+    status: "",
+    deptId: "",
+    params: {
+      roleNames: "司机",
     },
-    rules: {
-      id: [
-        { required: true, message: "不能为空", trigger: "blur" }
-      ],
-      userId: [
-        { required: true, message: "不能为空", trigger: "blur" }
-      ],
-      month: [
-        { required: true, message: "不能为空", trigger: "blur" }
-      ],
-      data: [
-        { required: true, message: "不能为空", trigger: "blur" }
-      ],
-    }
-  });
+  },
+  rules: {
+    id: [{ required: true, message: "不能为空", trigger: "blur" }],
+    userId: [{ required: true, message: "不能为空", trigger: "blur" }],
+    month: [{ required: true, message: "不能为空", trigger: "blur" }],
+    data: [{ required: true, message: "不能为空", trigger: "blur" }],
+  },
+});
 
-  const { queryParams,userParams,form, rules } = toRefs(data);
+const { queryParams, userParams, form, rules } = toRefs(data);
 
-  const getData = (data) => {
-    console.log(data.data)
-    var jsonData = JSON.parse(data.data)
-    if (jsonData.code == 0) {
-      console.log(jsonData.data.delivery_count)
-      return jsonData.data.delivery_count
-    }else{
-      return 0
-    }
+const getData = (data) => {
+  console.log(data.data);
+  var jsonData = JSON.parse(data.data);
+  if (jsonData.code == 0) {
+    console.log(jsonData.data.delivery_count);
+    return jsonData.data.delivery_count;
   }
+};
 
-  /** 查询【请填写功能名称】列表 */
-  const getList = async () => {
-    loading.value = true;
-    const res = await listExpressStatics(queryParams.value);
-    expressStaticsList.value = res.rows;
-    total.value = res.total;
-    loading.value = false;
+/** 查询【请填写功能名称】列表 */
+const getList = async () => {
+  loading.value = true;
+  let q = deepClone(queryParams.value);
+  if (q.params.ctime) {
+    q.params.ctime = moment(queryParams.value.params.ctime).format("YYYY-MM");
   }
+  const res = await listExpressStatics(q);
+  expressStaticsList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+};
 
-  const getUserList = async () => {
-    const res = await api.listUser(userParams.value);
-    console.log(res)
-    userList.value = res.rows;
-    getList();
-  }
+const getUserList = async () => {
+  const res = await api.listUser(userParams.value);
+  console.log(res);
+  userList.value = res.rows;
+  getList();
+};
 
-  /** 取消按钮 */
-  const cancel = () => {
-    reset();
-    dialog.visible = false;
-  }
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+};
 
-  /** 表单重置 */
-  const reset = () => {
-    form.value = { ...initFormData };
-    expressStaticsFormRef.value?.resetFields();
-  }
+/** 表单重置 */
+const reset = () => {
+  form.value = { ...initFormData };
+  expressStaticsFormRef.value?.resetFields();
+};
 
-  /** 搜索按钮操作 */
-  const handleQuery = () => {
-    queryParams.value.pageNum = 1;
-    getList();
-  }
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+};
 
-  /** 重置按钮操作 */
-  const resetQuery = () => {
-    queryFormRef.value?.resetFields();
-    handleQuery();
-  }
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+};
 
-  /** 多选框选中数据 */
-  const handleSelectionChange = (selection: ExpressStaticsVO[]) => {
-    ids.value = selection.map(item => item.id);
-    single.value = selection.length != 1;
-    multiple.value = !selection.length;
-  }
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: ExpressStaticsVO[]) => {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+};
 
-  /** 新增按钮操作 */
-  const handleAdd = () => {
-    reset();
-    dialog.visible = true;
-    dialog.title = "添加【请填写功能名称】";
-  }
+/** 新增按钮操作 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "添加【请填写功能名称】";
+};
 
-  /** 修改按钮操作 */
-  const handleUpdate = async (row?: ExpressStaticsVO) => {
-    reset();
-    const _id = row?.id || ids.value[0]
-    const res = await getExpressStatics(_id);
-    Object.assign(form.value, res.data);
-    dialog.visible = true;
-    dialog.title = "修改【请填写功能名称】";
-  }
+/** 修改按钮操作 */
+const handleUpdate = async (row?: ExpressStaticsVO) => {
+  reset();
+  const _id = row?.id || ids.value[0];
+  const res = await getExpressStatics(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改【请填写功能名称】";
+};
 
-  /** 提交按钮 */
-  const submitForm = () => {
-    expressStaticsFormRef.value?.validate(async (valid: boolean) => {
-      if (valid) {
-        buttonLoading.value = true;
-        if (form.value.id) {
-          await updateExpressStatics(form.value).finally(() => buttonLoading.value = false);
-        } else {
-          await addExpressStatics(form.value).finally(() => buttonLoading.value = false);
-        }
-        proxy?.$modal.msgSuccess("修改成功");
-        dialog.visible = false;
-        await getList();
+/** 提交按钮 */
+const submitForm = () => {
+  expressStaticsFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateExpressStatics(form.value).finally(
+          () => (buttonLoading.value = false)
+        );
+      } else {
+        await addExpressStatics(form.value).finally(() => (buttonLoading.value = false));
       }
-    });
-  }
-
-  const getUserName = (item) => {
-    console.log(item.userId)
-    for(var index in userList.value){
-       if(userList.value[index].userId == item.userId){
-        // console.log(userList.value[index])
-           return userList.value[index].nickName;
-       }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getList();
     }
-  }
+  });
+};
 
-  const getPhone = (item) => {
-    console.log(item.userId)
-    for(var index in userList.value){
-       if(userList.value[index].userId == item.userId){
-        // console.log(userList.value[index])
-           return userList.value[index].phonenumber;
-       }
+const getUserName = (item) => {
+  console.log(item.userId);
+  for (var index in userList.value) {
+    if (userList.value[index].userId == item.userId) {
+      // console.log(userList.value[index])
+      return userList.value[index].nickName;
     }
   }
+};
 
-  /** 删除按钮操作 */
-  const handleDelete = async (row?: ExpressStaticsVO) => {
-    const _ids = row?.id || ids.value;
-    await proxy?.$modal.confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
-    await delExpressStatics(_ids);
-    proxy?.$modal.msgSuccess("删除成功");
-    await getList();
-  }
+/** 删除按钮操作 */
+const handleDelete = async (row?: ExpressStaticsVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal
+    .confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项?')
+    .finally(() => (loading.value = false));
+  await delExpressStatics(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+};
 
-  /** 导出按钮操作 */
-  const handleExport = () => {
-    proxy?.download('system/expressStatics/export', {
-      ...queryParams.value
-    }, `expressStatics_${new Date().getTime()}.xlsx`)
-  }
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download(
+    "system/expressStatics/export",
+    {
+      ...queryParams.value,
+    },
+    `expressStatics_${new Date().getTime()}.xlsx`
+  );
+};
 
-  onMounted(() => {
-    getUserList();
-  });
-</script>
+onMounted(() => {
+  getUserList();
+});
+</script>

+ 455 - 0
src/views/upbag/index.vue

@@ -0,0 +1,455 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="88px">
+          <el-form-item label="快递柜编号" prop="deviceId">
+            <el-input v-model="queryParams.deviceId" placeholder="请输入快递柜编号" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="寄取时间" prop="scTime">
+            <el-date-picker clearable v-model="queryParams.scTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择寄取时间" />
+          </el-form-item>
+          <el-form-item label="快递公司" prop="cpCode">
+            <el-input v-model="queryParams.cpCode" placeholder="请输入快递公司" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="运单号" prop="waybillNo">
+            <el-input v-model="queryParams.waybillNo" placeholder="请输入运单号" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:bag:add']">新增</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:bag:edit']">修改</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:bag:remove']"
+              >删除</el-button
+            >
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:bag:export']">导出</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <input type="file" @change="uploadFile" style="display: none;" ref="filei" />
+            <el-button type="success" plain icon="Upload" @click="handlefile">导入</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Upload" :disabled="multiple" @click="handleSysc()" v-hasPermi="['system:bag:export']">
+              同步省平台
+            </el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="downloadmb">下载模版</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="bagList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="编号" align="center" prop="id" v-if="true" />
+        <el-table-column label="快递柜编号" align="center" prop="deviceId" >
+          <template #default="scope">
+            <el-tag>{{ Object.keys(sitelist).length>0?sitelist[scope.row.deviceId].dictLabel:"" }}</el-tag><span>{{ scope.row.deviceId }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="寄取" align="center" prop="scType" >
+          <template #default="scope">
+            <el-tag>{{ crk[scope.row.scType] }}</el-tag><span>{{ scope.row.scType }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="寄取时间" align="center" prop="scTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.scTime, "{y}-{m}-{d}") }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="快递公司" align="center" prop="cpCode" >
+          <template #default="scope">
+            <el-tag>{{ logisticsObject[scope.row.cpCode] }}</el-tag><span>{{ scope.row.cpCode }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="运单号" align="center" prop="waybillNo" />
+        <el-table-column label="备注" align="center" prop="remark" />
+        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="修改" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:bag:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="删除" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:bag:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 添加或修改【请填写功能名称】对话框 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="bagFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="快递柜编号" prop="deviceId">
+           <el-select v-model="form.deviceId" placeholder="请选择快递柜编号">
+            <el-option v-for="item in Object.values(sitelist)" :key="item.deviceId" :label="item.dictLabel" :value="item.deviceId" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="寄取类型" prop="scType">
+          <el-select v-model="form.scType" placeholder="请选择寄取类型">
+            <el-option label="下行派件入库" value="1" />
+            <el-option label="下行派件出库" value="2" />
+            <el-option label="上行揽件入库" value="3" />
+            <el-option label="上行派件出库" value="4" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="寄取时间" prop="scTime">
+          <el-date-picker clearable v-model="form.scTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择寄取时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="快递公司" prop="cpCode">
+          <el-select v-model="form.cpCode" placeholder="请选择快递公司">
+            <el-option v-for="item in Object.keys(logisticsObject)" :key="item" :label="logisticsObject[item]" :value="item">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="运单号" prop="waybillNo">
+          <el-input v-model="form.waybillNo" placeholder="请输入运单号" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="Bag" lang="ts">
+import { listBag, getBag, delBag, addBag, updateBag,sysc } from "@/api/system/upbag";
+import { BagVO, BagQuery, BagForm } from "@/api/system/upbag/types";
+import { listData } from "@/api/system/dict/data";
+import * as XLSX from 'xlsx'
+import cache from "@/plugins/cache";
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const bagList = ref<BagVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref<ElFormInstance>();
+const bagFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: "",
+});
+
+const logisticsObject = {
+    "STO": "申通",
+    "ZTO": "中通",
+    "YUNDA": "韵达",
+    "YTO": "圆通",
+    "SF": "顺丰",
+    "JT": "极兔",
+    "EMS": "邮政",
+    "JD": "京东",
+    "HT": "百世",
+    "TT": "天天",
+    "ANE": "安能",
+    "DP": "德邦",
+    "YS": "优速",
+    "ZJS": "宅急送",
+    "HW": "汇文",
+    "WPH": "唯品会",
+    "TMCS": "天猫超市",
+    "SN": "苏宁",
+    "FEDEX": "中国邦联",
+    "GT": "国通",
+    "KBTC": "快宝同城",
+    "DN": "丹鸟",
+    "ZYKD": "众邮",
+    "DDMC": "多多买菜",
+    "MTYX": "美团优选",
+    "CXYX": "橙心优选",
+    "XSYX": "兴盛优选",
+    "TCSH": "同程生活",
+    "SHT": "十荟团",
+    "FW": "丰网",
+    "OTHER": "其他"
+};
+const crk = {
+  "1": "下行派件入库",
+  "2": "下行派件出库",
+  "3": "上行揽件入库",
+  "4": "上行派件出库"
+}
+
+const sitelist = ref({});
+const getSites = () => {
+  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+  //@ts-ignore
+  listData({ dictType: "tbl_sites" }).then((res2) => {
+    res2.rows.filter(i=>i.remark.indexOf("cabinetType")!=-1).forEach((item) => {
+      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+      //@ts-ignore
+      item["deviceId"] = (JSON.parse(item.remark)??[]).filter(i=>i.type=="cabinet")[0]?.wdcode;
+      if(item["deviceId"]==undefined){
+        return;
+      }
+      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+      //@ts-ignore
+      sitelist.value[item["deviceId"]] = item;
+    });
+    console.log(sitelist.value)
+  });
+};
+
+const initFormData: BagForm = {
+  id: undefined,
+  deviceId: undefined,
+  scType: undefined,
+  scTime: undefined,
+  cpCode: undefined,
+  waybillNo: undefined,
+  remark: undefined,
+};
+const data = reactive<PageData<BagForm, BagQuery>>({
+  form: { ...initFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    deviceId: undefined,
+    scType: undefined,
+    scTime: undefined,
+    cpCode: undefined,
+    waybillNo: undefined,
+    params: {},
+  },
+  rules: {
+    id: [{ required: true, message: "编号不能为空", trigger: "blur" }],
+    deviceId: [{ required: true, message: "快递柜编号不能为空", trigger: "blur" }],
+    scType: [{ required: true, message: "寄取", trigger: "change" }],
+    scTime: [{ required: true, message: "寄取时间不能为空", trigger: "blur" }],
+    cpCode: [{ required: true, message: "快递公司不能为空", trigger: "blur" }],
+    waybillNo: [{ required: true, message: "运单号不能为空", trigger: "blur" }],
+    remark: [{ required: true, message: "备注不能为空", trigger: "blur" }],
+  },
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+const filei = ref(null);
+const upfile = ref(null);
+const handlefile = ()=>{
+  filei.value.click()
+}
+const uploadFile=(target)=>{
+  function parseExcelTime(cellValue) {
+  // Excel 时间序列号转换为 JavaScript 日期
+  const excelEpoch = new Date(1899, 11, 30);
+  const date = new Date(excelEpoch.getTime() + cellValue * 24 * 60 * 60 * 1000);
+  // 格式化为你需要的日期时间格式,这里示例为 yyyy-MM-dd HH:mm:ss
+  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
+}
+  readerData(target.target.files[0]).then(res=>{
+    let data = [];
+    try{
+       res.results.forEach(i=>{
+          let item = {};
+          item["deviceId"] = i["快递柜编号"];
+          item["scType"] = i["寄取类型"];
+          item["scTime"] = parseExcelTime(i["寄取时间"]);
+          item["cpCode"] = i["快递公司"];
+          item["waybillNo"] = i["运单号"];
+          data.push(item);
+       })
+    }catch(e){
+      ElMessage.error("请检查数据格式是否正确")
+    }
+    let index = 0;
+    data.forEach(i=>{
+      addBag(i).then((res1)=>{
+        index++;
+        if(index == data.length  ){
+          ElMessage.success("导入成功")
+          getList()
+        }
+       })
+    })
+
+
+  })
+}
+const downloadmb = ()=>{
+  window.open("/mb.xlsx")
+}
+
+
+const readerData = (rawFile) => {
+    return new Promise((resolve, reject) => {
+        // 创建一个文件读取的实例
+        const reader = new FileReader()
+        reader.onload = e => { // onload是加载完实例后执行(异步)
+            const data = e.target.result
+            const workbook = XLSX.read(data, { type: 'array' })
+            // 获取一张表的表名
+            const firstSheetName = workbook.SheetNames[0]
+            // 根据表名拿到表里面的内容
+            const worksheet = workbook.Sheets[firstSheetName]
+            // 解析成json
+            const results = XLSX.utils.sheet_to_json(worksheet)
+            // 获取表头数据
+            const header = getHeaderRow(worksheet)
+
+            resolve({ header, results })
+        }
+        // 读取成一个Buffer格式文件
+        reader.readAsArrayBuffer(rawFile)
+    })
+}
+// 获取表头数据
+const getHeaderRow = (sheet) => {
+    const headers = []
+    const range = XLSX.utils.decode_range(sheet['!ref'])
+    let C
+    const R = range.s.r
+    /* start in the first row */
+    for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
+        const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
+        /* find the cell in the first row */
+        let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
+        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
+        headers.push(hdr)
+    }
+    return headers
+}
+
+/** 查询【请填写功能名称】列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listBag(queryParams.value);
+  bagList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+};
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+};
+
+/** 表单重置 */
+const reset = () => {
+  form.value = { ...initFormData };
+  bagFormRef.value?.resetFields();
+};
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+};
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+};
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: BagVO[]) => {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+};
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "添加";
+};
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: BagVO) => {
+  reset();
+  const _id = row?.id || ids.value[0];
+  const res = await getBag(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改";
+};
+
+/** 提交按钮 */
+const submitForm = () => {
+  bagFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateBag(form.value).finally(() => (buttonLoading.value = false));
+      } else {
+        await addBag(form.value).finally(() => (buttonLoading.value = false));
+      }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+};
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: BagVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal
+    .confirm('是否确认删除编号为"' + _ids + '"的数据项?')
+    .finally(() => (loading.value = false));
+  await delBag(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+};
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download(
+    "upsystem/bag/export",
+    {
+      ...queryParams.value,
+    },
+    `bag_${new Date().getTime()}.xlsx`
+  );
+};
+
+
+const handleSysc = async (row?: BagVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal
+    .confirm('是否确认同步省平台数据?')
+    .finally(() => (loading.value = false));
+  await sysc(_ids);
+  proxy?.$modal.msgSuccess("同步成功");
+  await getList();
+};
+
+onMounted(() => {
+  getSites();
+  getList();
+});
+</script>

+ 462 - 345
src/views/yunying/sties/index.vue

@@ -2,30 +2,61 @@
 <template>
   <div class="p-2" style="padding: 10px">
     <div style="display: flex; flex-direction: row">
-      <div style="width: 20%;">
+      <div style="width: 20%">
         <div class="card-header">
           <div style="display: flex; flex-direction: row">
             <div style="width: 4px; height: 19px; opacity: 1; background: #409eff"></div>
-            <span style="
+            <span
+              style="
                 font-family: PingFang SC;
                 font-size: 14px;
                 font-weight: normal;
                 line-height: 19px;
                 height: 19px;
                 margin-left: 5px;
-              ">站点列表</span>
+              "
+              >站点列表</span
+            >
           </div>
         </div>
-        <div style="margin-top: 20px; padding-left: 10px;">
-          <el-select v-model="line" placeholder="请选择乡镇" style="width: 240px" @change="getCountrySites()">
-            <el-option v-for="item in countryList" :key="item.id" :label="item.name" :value="item.id" />
+        <div style="margin-top: 20px; padding-left: 10px">
+          <el-select
+            v-model="line"
+            placeholder="请选择乡镇"
+            style="width: 240px"
+            @change="getCountrySites()"
+          >
+            <el-option
+              v-for="item in countryList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
           </el-select>
-          <el-input style="margin-top: 10px;" v-model="filterText" placeholder="输入关键字" />
-          <el-tree-v2 v-if="showTree" style="margin-top: 10px;" ref="treeRef" class="filter-tree"
-            :height="gettreeheight()" :data="data" :indent="treeIndent" :props="defaultProps"
-            :filter-method="filterNode" @node-click="treeclick">
+          <el-input
+            style="margin-top: 10px"
+            v-model="filterText"
+            placeholder="输入关键字"
+          />
+          <el-tree-v2
+            v-if="showTree"
+            style="margin-top: 10px"
+            ref="treeRef"
+            class="filter-tree"
+            :height="gettreeheight()"
+            :data="data"
+            :indent="treeIndent"
+            :props="defaultProps"
+            :filter-method="filterNode"
+            @node-click="treeclick"
+          >
             <template v-slot:default="{ node }">
-              <element-tree-line :node="node" :treeData="data" :showLabelLine="false" :indent="treeIndent">
+              <element-tree-line
+                :node="node"
+                :treeData="data"
+                :showLabelLine="false"
+                :indent="treeIndent"
+              >
               </element-tree-line>
             </template>
           </el-tree-v2>
@@ -33,30 +64,43 @@
       </div>
       <div style="width: 77%; margin-left: 2%">
         <div class="card-header">
-          <div style="display: flex; flex-direction: row;position: relative">
+          <div style="display: flex; flex-direction: row; position: relative">
             <div style="width: 4px; height: 19px; opacity: 1; background: #409eff"></div>
-            <span style="
+            <span
+              style="
                 font-family: PingFang SC;
                 font-size: 14px;
                 font-weight: normal;
                 line-height: 19px;
                 height: 19px;
                 margin-left: 5px;
-              ">站点设备</span>
-            <span style="margin-left: 30px; font-size: 14px">{{ currentdata?.label }}</span>
-
-
+              "
+              >站点设备</span
+            >
+            <span style="margin-left: 30px; font-size: 14px">{{
+              currentdata?.label
+            }}</span>
           </div>
-          <el-button v-if="tableData.length < 4" type="primary" style="position: absolute;right: 20px;"
-            @click="goAdd">添加设备</el-button>
+          <el-button
+            v-if="tableData.length < 4"
+            type="primary"
+            style="position: absolute; right: 20px"
+            @click="goAdd"
+            >添加设备</el-button
+          >
         </div>
         <div style="margin-top: 20px">
           <el-table :data="tableData" border style="width: 100%">
             <el-table-column prop="name" label="设备名称" width="160">
               <template #default="scope">
                 <div>
-                  <span>{{ scope.row.name }}</span> <el-tag style="margin-left: 40px;" type="success"
-                    v-if="scope.row.type == 'cabinet'">{{ '在线' }}</el-tag>
+                  <span>{{ scope.row.name }}</span>
+                  <el-tag
+                    style="margin-left: 40px"
+                    type="success"
+                    v-if="scope.row.type == 'cabinet'"
+                    >{{ "在线" }}</el-tag
+                  >
                 </div>
               </template>
             </el-table-column>
@@ -68,24 +112,73 @@
                     v-if="scope.row.type == 'cabinet'">{{ `共 ${currentCabinet.total} 格` }}<span
                       style="margin-left: 5px;color:green">{{ `可用 ${currentCabinet.total - currentCabinet.unused} 格`
                       }}</span></span> -->
-                  <span style="margin-left: 20px;" v-if="scope.row.type == 'cabinet'">{{ getTypeName(scope.row)
-                    }}</span>
+                  <span style="margin-left: 20px" v-if="scope.row.type == 'cabinet'">{{
+                    getTypeName(scope.row)
+                  }}</span>
                 </div>
               </template>
             </el-table-column>
             <el-table-column prop="code" label="设备序列号">
               <template #default="scope">
-                <div style="display: flex;flex-wrap: nowrap;align-items: center;justify-content: space-between;">
-                  <el-input v-model="scope.row.code" style="width: 240px" placeholder="请输入" />
-                  <el-button type="primary" size="small" @click="savedata">保存</el-button>
+                <div
+                  style="
+                    display: flex;
+                    flex-wrap: nowrap;
+                    align-items: center;
+                    justify-content: space-between;
+                  "
+                >
+                  <el-input
+                    v-model="scope.row.code"
+                    style="width: 240px"
+                    placeholder="请输入"
+                  />
+                  <el-button type="primary" size="small" @click="savedata"
+                    >保存</el-button
+                  >
                 </div>
               </template>
             </el-table-column>
+            <el-table-column prop="wdcode" label="网点编号">
+              <template #default="scope">
+                <div
+                  v-if="scope.row.type == 'cabinet'"
+                  style="
+                    display: flex;
+                    flex-wrap: nowrap;
+                    align-items: center;
+                    justify-content: space-between;
+                  "
+                >
+                  <el-input
+                    v-model="scope.row.wdcode"
+                    style="width: 240px"
+                    placeholder="请输入"
+                  />
+                  <el-button type="primary" size="small" @click="savedata"
+                    >保存</el-button
+                  >
+                </div>
+                <div v-else>--</div>
+              </template>
+            </el-table-column>
             <el-table-column prop="code" label="操作">
               <template #default="scope">
                 <div>
-                  <el-button type="danger" link size="small" @click="deleteDevice(scope.row)">删除</el-button>
-                  <el-button v-if="scope.row.type == 'cabinet'" type="primary" link size="small">立即同步</el-button>
+                  <el-button
+                    type="danger"
+                    link
+                    size="small"
+                    @click="deleteDevice(scope.row)"
+                    >删除</el-button
+                  >
+                  <el-button
+                    v-if="scope.row.type == 'cabinet'"
+                    type="primary"
+                    link
+                    size="small"
+                    >立即同步</el-button
+                  >
                 </div>
               </template>
             </el-table-column>
@@ -120,10 +213,26 @@
         </el-form-item>
         <el-form-item label="类型">
           <el-select v-model="formdata.type" placeholder="请选择设备类型">
-            <el-option v-if="tableData.filter(i => i.type == 'tts').length < 1" label="tts" value="tts" />
-            <el-option v-if="tableData.filter(i => i.type == 'led').length < 1" label="led" value="led" />
-            <el-option v-if="tableData.filter(i => i.type == 'cabinet').length < 1" label="快递柜" value="cabinet" />
-            <el-option v-if="tableData.filter(i => i.type == 'camera').length < 1" label="摄像头" value="camera" />
+            <el-option
+              v-if="tableData.filter((i) => i.type == 'tts').length < 1"
+              label="tts"
+              value="tts"
+            />
+            <el-option
+              v-if="tableData.filter((i) => i.type == 'led').length < 1"
+              label="led"
+              value="led"
+            />
+            <el-option
+              v-if="tableData.filter((i) => i.type == 'cabinet').length < 1"
+              label="快递柜"
+              value="cabinet"
+            />
+            <el-option
+              v-if="tableData.filter((i) => i.type == 'camera').length < 1"
+              label="摄像头"
+              value="camera"
+            />
           </el-select>
         </el-form-item>
         <el-form-item label="快递类型" v-if="formdata.type == 'cabinet'">
@@ -136,369 +245,377 @@
         <el-form-item label="序列号">
           <el-input v-model="formdata.code" />
         </el-form-item>
+        <el-form-item label="网点编号">
+          <el-input v-model="formdata.wdcode" />
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="dialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="addDevice">
-            保存
-          </el-button>
+          <el-button type="primary" @click="addDevice"> 保存 </el-button>
         </div>
       </template>
-
-
     </el-dialog>
-
   </div>
 </template>
 
 <script setup name="CarInfo" lang="ts">
-  import { listCountry, getCountry, delCountry, addCountry, updateCountry } from '@/api/country';
-  import { TreeNode } from "element-plus";
-  import { useRoute, useRouter } from "vue-router";
-  import EZUIKit from 'ezuikit-js';
-  import { getCameraPlayerConfig } from '@/api/gpsData';
-  import { listCarPath, getCarPath, delCarPath, addCarPath, updateCarPath } from '@/api/carPath';
-  import { updateData, listData } from "@/api/system/dict/data";
-  import imgulock from "@/assets/images/unlock@2x.png";
-
-  const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-
-  const sites = ref([]);
-
-  const showTree = ref(true)
-
-
-  const formdata = ref({
+import {
+  listCountry,
+  getCountry,
+  delCountry,
+  addCountry,
+  updateCountry,
+} from "@/api/country";
+import { TreeNode } from "element-plus";
+import { useRoute, useRouter } from "vue-router";
+import EZUIKit from "ezuikit-js";
+import { getCameraPlayerConfig } from "@/api/gpsData";
+import {
+  listCarPath,
+  getCarPath,
+  delCarPath,
+  addCarPath,
+  updateCarPath,
+} from "@/api/carPath";
+import { updateData, listData } from "@/api/system/dict/data";
+import imgulock from "@/assets/images/unlock@2x.png";
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const sites = ref([]);
+
+const showTree = ref(true);
+
+const formdata = ref({
+  name: "",
+  type: "",
+  code: "",
+  wdcode: "",
+  cabinetType: "",
+});
+
+const route = useRoute();
+const router = useRouter();
+
+const tableData = ref([]);
+const carPathList = ref([]);
+const countryList = ref([]);
+const line = ref([]);
+
+const activeName = ref("camera");
+
+const filterText = ref("");
+const treeRef = ref(null);
+const dialogVisible = ref(false);
+
+const gettreeheight = () => {
+  return document.body.clientHeight - 300;
+};
+
+const goAdd = () => {
+  dialogVisible.value = true;
+  formdata.value = {
     name: "",
     type: "",
     code: "",
-    cabinetType: ''
-  })
-
-
-  const route = useRoute();
-  const router = useRouter();
-
-  const tableData = ref([]);
-  const carPathList = ref([]);
-  const countryList = ref([])
-  const line = ref([]);
-
-  const activeName = ref("camera")
-
-  const filterText = ref("");
-  const treeRef = ref(null);
-  const dialogVisible = ref(false);
-
-  const gettreeheight = () => {
-    return document.body.clientHeight - 300;
-  }
-
-  const goAdd = () => {
-    dialogVisible.value = true
-    formdata.value = {
-      name: "",
-      type: "",
-      code: ""
-    }
-  }
-
-  const getTypeName = (data) => {
-    var type = data.cabinetType
-    if (type == 1) {
-      return '一主'
-    } else if (type == 2) {
-      return '一主一副'
-    } else {
-      return '一主二副'
-    }
+  };
+};
+
+const getTypeName = (data) => {
+  var type = data.cabinetType;
+  if (type == 1) {
+    return "一主";
+  } else if (type == 2) {
+    return "一主一副";
+  } else {
+    return "一主二副";
   }
+};
 
-  const initData = async () => {
-    const res = await listCarPath({ pageSize: 1000 });
-    carPathList.value = res.rows;
-  }
+const initData = async () => {
+  const res = await listCarPath({ pageSize: 1000 });
+  carPathList.value = res.rows;
+};
 
-  const getCountry = () => {
-    listCountry({ pageSize: 10000 }).then(res => {
-      console.log(res)
-      countryList.value = res.rows
-    })
-  }
-
-  const getCountrySites = () => {
-    for (var i in countryList.value) {
-      if (line.value == countryList.value[i].id) {
-        console.log(countryList.value[i].sites)
-        var siteList = countryList.value[i].sites.split(",")
-        var siteObjList = [];
-        for (var j in sites.value) {
-          if (siteList.indexOf(sites.value[j].dictCode) > -1) {
-            siteObjList.push(sites.value[j])
-          }
+const getCountry = () => {
+  listCountry({ pageSize: 10000 }).then((res) => {
+    console.log(res);
+    countryList.value = res.rows;
+  });
+};
+
+const getCountrySites = () => {
+  for (var i in countryList.value) {
+    if (line.value == countryList.value[i].id) {
+      console.log(countryList.value[i].sites);
+      var siteList = countryList.value[i].sites.split(",");
+      var siteObjList = [];
+      for (var j in sites.value) {
+        if (siteList.indexOf(sites.value[j].dictCode) > -1) {
+          siteObjList.push(sites.value[j]);
         }
-        updateSites(siteObjList)
       }
+      updateSites(siteObjList);
     }
   }
+};
 
-  const updateSites = (sitesList) => {
-    console.log(sitesList)
-    var sites = []
-    for (var i in sitesList) {
-      
-      sites.push({ id: i, label: sitesList[i].dictLabel })
-    }
-    console.log(sites)
-    data.value = [{
+const updateSites = (sitesList) => {
+  console.log(sitesList);
+  var sites = [];
+  for (var i in sitesList) {
+    sites.push({ id: i, label: sitesList[i].dictLabel });
+  }
+  console.log(sites);
+  data.value = [
+    {
       id: 1,
       label: "站点",
-    },];
-    data.value[0].children = sites
-    console.log(data.value)
-    showTree.value = false;
-    setTimeout(() => {
-      showTree.value = true
-    }, 100);
+    },
+  ];
+  data.value[0].children = sites;
+  console.log(data.value);
+  showTree.value = false;
+  setTimeout(() => {
+    showTree.value = true;
+  }, 100);
+};
+
+const defaultProps = {
+  children: "children",
+  label: "label",
+  value: "id",
+};
+const treeIndent = ref(40);
+
+watch(filterText, (val) => {
+  if (treeRef.value) {
+    treeRef.value.filter(val);
   }
-
-
-  const defaultProps = {
-    children: "children",
-    label: "label",
-    value: 'id',
+});
+
+const savedata = () => {
+  //保存数据
+  var data = {
+    dictCode: currentdata.value.dictCode,
+    dictValue: currentdata.value.dictValue,
+    dictLabel: currentdata.value.dictLabel,
+    dictType: "tbl_sites",
+    remark: JSON.stringify(tableData.value),
   };
-  const treeIndent = ref(40);
-
-  watch(filterText, (val) => {
-    if (treeRef.value) {
-      treeRef.value.filter(val);
-    }
+  updateData(data).then((res) => {
+    ElMessage.success("成功!");
+    window.location.reload();
   });
-
-  const savedata = () => {
-    //保存数据
-    var data = {
-      dictCode: currentdata.value.dictCode,
-      dictValue: currentdata.value.dictValue,
-      dictLabel: currentdata.value.dictLabel,
-      dictType: "tbl_sites",
-      remark: JSON.stringify(tableData.value)
+};
+
+const getLineSites = () => {
+  console.log(line.value);
+  var sitesList = [];
+  for (var index in carPathList.value) {
+    if (carPathList.value[index].id == line.value) {
+      sitesList = JSON.parse(carPathList.value[index].stationList);
     }
-    updateData(data).then(res => {
-      ElMessage.success("成功!");
-      getLineSites();
-
-    })
   }
-
-  const getLineSites = () => {
-    console.log(line.value)
-    var sitesList = []
-    for (var index in carPathList.value) {
-      if (carPathList.value[index].id == line.value) {
-        sitesList = JSON.parse(carPathList.value[index].stationList)
-      }
-    }
-    var sites = []
-    for (var i in sitesList) {
-      sites.push({ id: i, label: sitesList[i].data.dictLabel })
-    }
-    console.log(sites)
-    data.value = [{
+  var sites = [];
+  for (var i in sitesList) {
+    sites.push({ id: i, label: sitesList[i].data.dictLabel });
+  }
+  console.log(sites);
+  data.value = [
+    {
       id: 1,
       label: "站点",
-    },];
-    data.value[0].children = sites
-    console.log(data.value)
-    showTree.value = false;
-    setTimeout(() => {
-      showTree.value = true
-    }, 100);
-
-  }
-
-  const getSites = () => {
-    listData({ dictType: "tbl_sites" }).then(res2 => {
-      sites.value = res2.rows;
-      var index = 1;
-      data.value = [{
+    },
+  ];
+  data.value[0].children = sites;
+  console.log(data.value);
+  showTree.value = false;
+  setTimeout(() => {
+    showTree.value = true;
+  }, 100);
+};
+
+const getSites = () => {
+  listData({ dictType: "tbl_sites" }).then((res2) => {
+    sites.value = res2.rows;
+    var index = 1;
+    data.value = [
+      {
         id: 1,
         label: "站点",
-        children: sites.value.map(i => { return { id: ++index, label: i.dictLabel } }),
-      },];
-    });
-  }
-
-  const deleteDevice = (datac) => {
-    tableData.value = tableData.value.filter(i => i.type != datac.type);
-    var data = {
-      dictCode: currentdata.value.dictCode,
-      dictValue: currentdata.value.dictValue,
-      dictLabel: currentdata.value.dictLabel,
-      dictType: "tbl_sites",
-      remark: JSON.stringify(tableData.value)
-    }
-    updateData(data).then(res => {
-      ElMessage.success("成功!");
-    })
-  }
-
-  const handleTabClick = () => {
-
-  }
-
-  const filterNode = (value: string, node: TreeNode) => {
-    if (node.id == 1) return true;
-    console.log(node.label.indexOf(value) != -1)
-    return node.label.indexOf(value) != -1;
+        children: sites.value.map((i) => {
+          return { id: ++index, label: i.dictLabel };
+        }),
+      },
+    ];
+  });
+};
+
+const deleteDevice = (datac) => {
+  tableData.value = tableData.value.filter((i) => i.type != datac.type);
+  var data = {
+    dictCode: currentdata.value.dictCode,
+    dictValue: currentdata.value.dictValue,
+    dictLabel: currentdata.value.dictLabel,
+    dictType: "tbl_sites",
+    remark: JSON.stringify(tableData.value),
   };
+  updateData(data).then((res) => {
+    ElMessage.success("成功!");
+  });
+};
 
-  const currentdata = ref(null)
+const handleTabClick = () => {};
 
-  const isJSON = (str) => {
-    if (typeof str == 'string') {
-      try {
-        var obj = JSON.parse(str);
-        if (typeof obj == 'object' && obj) {
-          return true;
-        } else {
-          return false;
-        }
+const filterNode = (value: string, node: TreeNode) => {
+  if (node.id == 1) return true;
+  console.log(node.label.indexOf(value) != -1);
+  return node.label.indexOf(value) != -1;
+};
+
+const currentdata = ref(null);
 
-      } catch (e) {
+const isJSON = (str) => {
+  if (typeof str == "string") {
+    try {
+      var obj = JSON.parse(str);
+      if (typeof obj == "object" && obj) {
+        return true;
+      } else {
         return false;
       }
+    } catch (e) {
+      return false;
     }
   }
-
-  const treeclick = (data: TreeNodeData, node: TreeNode) => {
-
-    currentdata.value = sites.value.filter(i => {
-      return i.dictLabel == data.label
-    })[0];
-    tableData.value = [];
-    if (currentdata.value) {
-      // if (isJSON(currentdata.value.remark)) {
-      tableData.value = JSON.parse((currentdata.value.remark == '' ? "[]" : currentdata.value.remark) ?? "[]");
-      var cameras = tableData.value.filter(i => i.type == 'camera');
-      if (cameras.length > 0) {
-        var cameracode = cameras[0].code;
-        //存在视频播放视频
-        // getCameraPlayerConfig(cameracode).then(res => {
-        //   console.log(res.data);
-        //   var player = new EZUIKit.EZUIKitPlayer({
-        //     template: "pcLive",
-        //     id: 'video-container', // 视频容器ID
-        //     ...res.data
-        //   })
-        // })
-      }
-
-      var cabinets = tableData.value.filter(i => i.type == 'cabinet');
-      if (cabinets.length > 0) {
-        var cabinetcode = cameras[0].code;
-        SycCabinet(cabinetcode);
-      }
-      // }else{
-      //   ElMessage.warning("站点设备配置错误");
-      // }
+};
+
+const treeclick = (data: TreeNodeData, node: TreeNode) => {
+  currentdata.value = sites.value.filter((i) => {
+    return i.dictLabel == data.label;
+  })[0];
+  tableData.value = [];
+  if (currentdata.value) {
+    // if (isJSON(currentdata.value.remark)) {
+    tableData.value = JSON.parse(
+      (currentdata.value.remark == "" ? "[]" : currentdata.value.remark) ?? "[]"
+    );
+    var cameras = tableData.value.filter((i) => i.type == "camera");
+    if (cameras.length > 0) {
+      var cameracode = cameras[0].code;
+      //存在视频播放视频
+      // getCameraPlayerConfig(cameracode).then(res => {
+      //   console.log(res.data);
+      //   var player = new EZUIKit.EZUIKitPlayer({
+      //     template: "pcLive",
+      //     id: 'video-container', // 视频容器ID
+      //     ...res.data
+      //   })
+      // })
     }
 
-  }
-
-
-  const addDevice = () => {
-    dialogVisible.value = false;
-    if (formdata.value.name == "") {
-      ElMessage.warning("设备名称未填写");
-      return;
-    }
-    if (formdata.value.type == "") {
-      ElMessage.warning("设备类型未填写");
-      return;
-    }
-    if (formdata.value.code == "") {
-      ElMessage.warning("设备序列号未填写");
-      return;
-    }
-    if (tableData.value.filter(i => i.type == formdata.value.type).length > 0) {
-      ElMessage.warning("存在相同类型的设备");
-      return;
-    }
-    tableData.value.push(formdata.value);
-    var data = {
-      dictCode: currentdata.value.dictCode,
-      dictValue: currentdata.value.dictValue,
-      dictLabel: currentdata.value.dictLabel,
-      dictType: "tbl_sites",
-      remark: JSON.stringify(tableData.value)
+    var cabinets = tableData.value.filter((i) => i.type == "cabinet");
+    if (cabinets.length > 0) {
+      var cabinetcode = cameras[0].code;
+      SycCabinet(cabinetcode);
     }
-    updateData(data).then(res => {
-      ElMessage.success("成功!");
-    })
-
-
+    // }else{
+    //   ElMessage.warning("站点设备配置错误");
+    // }
   }
+};
 
-  const currentCabinet = ref({
-    total: 40,
-    unused: 10,
-    boxlist: []
-  })
-  const SycCabinet = (code) => {
-    //TODO 获取格数
-    // var toalnum
-    currentCabinet.value.boxlist = [];
-    for (var i = 0; i < currentCabinet.value.total; i++) {
-      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
-      //@ts-ignore
-      currentCabinet.value.boxlist.push({
-        box_id: 1,
-        box_name: (i + 1) + "",
-        box_status: i % 2
-      }
-      )
-    }
+const addDevice = () => {
+  dialogVisible.value = false;
+  if (formdata.value.name == "") {
+    ElMessage.warning("设备名称未填写");
+    return;
   }
-  const openbox = (code) => {
-    setTimeout(() => {
-      ElMessage.success("指令已发送!");
-    }, 1000);
+  if (formdata.value.type == "") {
+    ElMessage.warning("设备类型未填写");
+    return;
   }
-
-
-  const data = computed(() => {
-
-    var index = 1;
-
-    return [{
+  if (formdata.value.code == "") {
+    ElMessage.warning("设备序列号未填写");
+    return;
+  }
+  if (tableData.value.filter((i) => i.type == formdata.value.type).length > 0) {
+    ElMessage.warning("存在相同类型的设备");
+    return;
+  }
+  tableData.value.push(formdata.value);
+  var data = {
+    dictCode: currentdata.value.dictCode,
+    dictValue: currentdata.value.dictValue,
+    dictLabel: currentdata.value.dictLabel,
+    dictType: "tbl_sites",
+    remark: JSON.stringify(tableData.value),
+  };
+  updateData(data).then((res) => {
+    ElMessage.success("成功!");
+  });
+};
+
+const currentCabinet = ref({
+  total: 40,
+  unused: 10,
+  boxlist: [],
+});
+const SycCabinet = (code) => {
+  //TODO 获取格数
+  // var toalnum
+  currentCabinet.value.boxlist = [];
+  for (var i = 0; i < currentCabinet.value.total; i++) {
+    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+    //@ts-ignore
+    currentCabinet.value.boxlist.push({
+      box_id: 1,
+      box_name: i + 1 + "",
+      box_status: i % 2,
+    });
+  }
+};
+const openbox = (code) => {
+  setTimeout(() => {
+    ElMessage.success("指令已发送!");
+  }, 1000);
+};
+
+const data = computed(() => {
+  var index = 1;
+
+  return [
+    {
       id: 1,
       label: "站点",
-      children: sites.value.map(i => { return { id: ++index, label: i.dictLabel } }),
-    },]
-  });
-  onMounted(() => {
-    if (treeRef.value) {
-      setTimeout(() => {
-        treeRef.value.expandNode(treeRef.value.getNode(1))
-      }, 100);
-      getSites();
-      getCountry();
-      // treeRef.value.expandNode(treeRef.value.getNode(1))
-    }
-  });
+      children: sites.value.map((i) => {
+        return { id: ++index, label: i.dictLabel };
+      }),
+    },
+  ];
+});
+onMounted(() => {
+  if (treeRef.value) {
+    setTimeout(() => {
+      treeRef.value.expandNode(treeRef.value.getNode(1));
+    }, 100);
+    getSites();
+    getCountry();
+    // treeRef.value.expandNode(treeRef.value.getNode(1))
+  }
+});
 </script>
 
 <style lang="scss" scoped>
-  .card-header {
-    display: flex;
-    flex-direction: row;
-    justify-content: space-between;
-  }
-
-  .boxunused {
-    background: #3333332d;
-  }
-</style>
+.card-header {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+}
+
+.boxunused {
+  background: #3333332d;
+}
+</style>

+ 1 - 1
vite.config.ts

@@ -27,7 +27,7 @@ export default defineConfig(({ mode, command }: ConfigEnv): UserConfig => {
       proxy: {
         [env.VITE_APP_BASE_API]: {
           // target: 'http://localhost:8080',
-          target: 'http://47.104.97.60/api',
+          target: 'https://khy.xiaole.vip/api',
           changeOrigin: true,
           ws: true,
           rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')