wenhongquan 1 год назад
Родитель
Сommit
e926cfef6e

+ 0 - 63
src/api/ article/index.ts

@@ -1,63 +0,0 @@
-import request from '@/utils/request';
-import { AxiosPromise } from 'axios';
-import {  articleVO,  articleForm,  articleQuery } from '@/api/system/ article/types';
-
-/**
- * 查询文章列表
- * @param query
- * @returns {*}
- */
-
-export const list article = (query?:  articleQuery): AxiosPromise< articleVO[]> => {
-  return request({
-    url: '/system/ article/list',
-    method: 'get',
-    params: query
-  });
-};
-
-/**
- * 查询文章详细
- * @param id
- */
-export const get article = (id: string | number): AxiosPromise< articleVO> => {
-  return request({
-    url: '/system/ article/' + id,
-    method: 'get'
-  });
-};
-
-/**
- * 新增文章
- * @param data
- */
-export const add article = (data:  articleForm) => {
-  return request({
-    url: '/system/ article',
-    method: 'post',
-    data: data
-  });
-};
-
-/**
- * 修改文章
- * @param data
- */
-export const update article = (data:  articleForm) => {
-  return request({
-    url: '/system/ article',
-    method: 'put',
-    data: data
-  });
-};
-
-/**
- * 删除文章
- * @param id
- */
-export const del article = (id: string | number | Array<string | number>) => {
-  return request({
-    url: '/system/ article/' + id,
-    method: 'delete'
-  });
-};

+ 0 - 116
src/api/ article/types.ts

@@ -1,116 +0,0 @@
-export interface  articleVO {
-  /**
-   * 编号
-   */
-  id: string | number;
-
-  /**
-   * 标题
-   */
-  title: string;
-
-  /**
-   * 副标题
-   */
-  subTitle: string;
-
-  /**
-   * 内容
-   */
-  content: string;
-
-  /**
-   * 状态
-   */
-  status: number;
-
-  /**
-   * 扩展1
-   */
-  ext1: string;
-
-  /**
-   * 扩展2
-   */
-  ext2: string;
-
-}
-
-export interface  articleForm extends BaseEntity {
-  /**
-   * 编号
-   */
-  id?: string | number;
-
-  /**
-   * 标题
-   */
-  title?: string;
-
-  /**
-   * 副标题
-   */
-  subTitle?: string;
-
-  /**
-   * 内容
-   */
-  content?: string;
-
-  /**
-   * 状态
-   */
-  status?: number;
-
-  /**
-   * 扩展1
-   */
-  ext1?: string;
-
-  /**
-   * 扩展2
-   */
-  ext2?: string;
-
-}
-
-export interface  articleQuery extends PageQuery {
-
-  /**
-   * 标题
-   */
-  title?: string;
-
-  /**
-   * 副标题
-   */
-  subTitle?: string;
-
-  /**
-   * 内容
-   */
-  content?: string;
-
-  /**
-   * 状态
-   */
-  status?: number;
-
-  /**
-   * 扩展1
-   */
-  ext1?: string;
-
-  /**
-   * 扩展2
-   */
-  ext2?: string;
-
-    /**
-     * 日期范围参数
-     */
-    params?: any;
-}
-
-
-

+ 63 - 0
src/api/system/bag/index.ts

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

+ 191 - 0
src/api/system/bag/types.ts

@@ -0,0 +1,191 @@
+export interface BagVO {
+  /**
+   * id
+   */
+  id: string | number;
+
+  /**
+   * 快递公司
+   */
+  bagCompany: string;
+
+  /**
+   * 快递单号
+   */
+  bagNumber: string;
+
+  /**
+   * 出库状态,待取件0,出库1,异常2,异常已处理3
+   */
+  bagStatus: string;
+
+  /**
+   * 出库时间
+   */
+  bagOutTime: string;
+
+  /**
+   * 货架号
+   */
+  bagLocal: string;
+
+  /**
+   * 层号
+   */
+  bagLocal2: string;
+
+  /**
+   * 入库时间,停用
+   */
+  bagInTime: string;
+
+  /**
+   * 异常原因,如退件、损坏等
+   */
+  bagReason: string;
+
+  /**
+   * 所在站点
+   */
+  bagSite: string;
+
+  /**
+   * 修改时间
+   */
+  updatedAt: string;
+
+  /**
+   * 创建时间,入库时间
+   */
+  createdAt: string;
+
+}
+
+export interface BagForm extends BaseEntity {
+  /**
+   * id
+   */
+  id?: string | number;
+
+  /**
+   * 快递公司
+   */
+  bagCompany?: string;
+
+  /**
+   * 快递单号
+   */
+  bagNumber?: string;
+
+  /**
+   * 出库状态,待取件0,出库1,异常2,异常已处理3
+   */
+  bagStatus?: string;
+
+  /**
+   * 出库时间
+   */
+  bagOutTime?: string;
+
+  /**
+   * 货架号
+   */
+  bagLocal?: string;
+
+  /**
+   * 层号
+   */
+  bagLocal2?: string;
+
+  /**
+   * 入库时间,停用
+   */
+  bagInTime?: string;
+
+  /**
+   * 异常原因,如退件、损坏等
+   */
+  bagReason?: string;
+
+  /**
+   * 所在站点
+   */
+  bagSite?: string;
+
+  /**
+   * 修改时间
+   */
+  updatedAt?: string;
+
+  /**
+   * 创建时间,入库时间
+   */
+  createdAt?: string;
+
+}
+
+export interface BagQuery extends PageQuery {
+
+  /**
+   * 快递公司
+   */
+  bagCompany?: string;
+
+  /**
+   * 快递单号
+   */
+  bagNumber?: string;
+
+  /**
+   * 出库状态,待取件0,出库1,异常2,异常已处理3
+   */
+  bagStatus?: string;
+
+  /**
+   * 出库时间
+   */
+  bagOutTime?: string;
+
+  /**
+   * 货架号
+   */
+  bagLocal?: string;
+
+  /**
+   * 层号
+   */
+  bagLocal2?: string;
+
+  /**
+   * 入库时间,停用
+   */
+  bagInTime?: string;
+
+  /**
+   * 异常原因,如退件、损坏等
+   */
+  bagReason?: string;
+
+  /**
+   * 所在站点
+   */
+  bagSite?: string;
+
+  /**
+   * 修改时间
+   */
+  updatedAt?: string;
+
+  /**
+   * 创建时间,入库时间
+   */
+  createdAt?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/system/companycode/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { CompanycodeVO, CompanycodeForm, CompanycodeQuery } from '@/api/system/companycode/types';
+
+/**
+ * 查询【请填写功能名称】列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listCompanycode = (query?: CompanycodeQuery): AxiosPromise<CompanycodeVO[]> => {
+  return request({
+    url: '/system/companycode/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询【请填写功能名称】详细
+ * @param id
+ */
+export const getCompanycode = (id: string | number): AxiosPromise<CompanycodeVO> => {
+  return request({
+    url: '/system/companycode/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增【请填写功能名称】
+ * @param data
+ */
+export const addCompanycode = (data: CompanycodeForm) => {
+  return request({
+    url: '/system/companycode',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改【请填写功能名称】
+ * @param data
+ */
+export const updateCompanycode = (data: CompanycodeForm) => {
+  return request({
+    url: '/system/companycode',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除【请填写功能名称】
+ * @param id
+ */
+export const delCompanycode = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/system/companycode/' + id,
+    method: 'delete'
+  });
+};

+ 56 - 0
src/api/system/companycode/types.ts

@@ -0,0 +1,56 @@
+export interface CompanycodeVO {
+  /**
+   * 
+   */
+  id: string | number;
+
+  /**
+   * 
+   */
+  ShipperCode: string;
+
+  /**
+   * 
+   */
+  Company: string;
+
+}
+
+export interface CompanycodeForm extends BaseEntity {
+  /**
+   * 
+   */
+  id?: string | number;
+
+  /**
+   * 
+   */
+  ShipperCode?: string;
+
+  /**
+   * 
+   */
+  Company?: string;
+
+}
+
+export interface CompanycodeQuery extends PageQuery {
+
+  /**
+   * 
+   */
+  ShipperCode?: string;
+
+  /**
+   * 
+   */
+  Company?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/system/punter/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { PunterVO, PunterForm, PunterQuery } from '@/api/system/punter/types';
+
+/**
+ * 查询【请填写功能名称】列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listPunter = (query?: PunterQuery): AxiosPromise<PunterVO[]> => {
+  return request({
+    url: '/system/punter/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询【请填写功能名称】详细
+ * @param id
+ */
+export const getPunter = (id: string | number): AxiosPromise<PunterVO> => {
+  return request({
+    url: '/system/punter/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增【请填写功能名称】
+ * @param data
+ */
+export const addPunter = (data: PunterForm) => {
+  return request({
+    url: '/system/punter',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改【请填写功能名称】
+ * @param data
+ */
+export const updatePunter = (data: PunterForm) => {
+  return request({
+    url: '/system/punter',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除【请填写功能名称】
+ * @param id
+ */
+export const delPunter = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/system/punter/' + id,
+    method: 'delete'
+  });
+};

+ 131 - 0
src/api/system/punter/types.ts

@@ -0,0 +1,131 @@
+export interface PunterVO {
+  /**
+   * 
+   */
+  id: string | number;
+
+  /**
+   * 
+   */
+  address: string;
+
+  /**
+   * 
+   */
+  telnumber: string;
+
+  /**
+   * 
+   */
+  createdAt: string;
+
+  /**
+   * 
+   */
+  updatedAt: string;
+
+  /**
+   * 
+   */
+  puntername: string;
+
+  /**
+   * 
+   */
+  notes: string;
+
+  /**
+   * 
+   */
+  site: string;
+
+}
+
+export interface PunterForm extends BaseEntity {
+  /**
+   * 
+   */
+  id?: string | number;
+
+  /**
+   * 
+   */
+  address?: string;
+
+  /**
+   * 
+   */
+  telnumber?: string;
+
+  /**
+   * 
+   */
+  createdAt?: string;
+
+  /**
+   * 
+   */
+  updatedAt?: string;
+
+  /**
+   * 
+   */
+  puntername?: string;
+
+  /**
+   * 
+   */
+  notes?: string;
+
+  /**
+   * 
+   */
+  site?: string;
+
+}
+
+export interface PunterQuery extends PageQuery {
+
+  /**
+   * 
+   */
+  address?: string;
+
+  /**
+   * 
+   */
+  telnumber?: string;
+
+  /**
+   * 
+   */
+  createdAt?: string;
+
+  /**
+   * 
+   */
+  updatedAt?: string;
+
+  /**
+   * 
+   */
+  puntername?: string;
+
+  /**
+   * 
+   */
+  notes?: string;
+
+  /**
+   * 
+   */
+  site?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 63 - 0
src/api/system/site/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { SiteVO, SiteForm, SiteQuery } from '@/api/system/site/types';
+
+/**
+ * 查询【请填写功能名称】列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listSite = (query?: SiteQuery): AxiosPromise<SiteVO[]> => {
+  return request({
+    url: '/system/site/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询【请填写功能名称】详细
+ * @param id
+ */
+export const getSite = (id: string | number): AxiosPromise<SiteVO> => {
+  return request({
+    url: '/system/site/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增【请填写功能名称】
+ * @param data
+ */
+export const addSite = (data: SiteForm) => {
+  return request({
+    url: '/system/site',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改【请填写功能名称】
+ * @param data
+ */
+export const updateSite = (data: SiteForm) => {
+  return request({
+    url: '/system/site',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除【请填写功能名称】
+ * @param id
+ */
+export const delSite = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/system/site/' + id,
+    method: 'delete'
+  });
+};

+ 146 - 0
src/api/system/site/types.ts

@@ -0,0 +1,146 @@
+export interface SiteVO {
+  /**
+   * 
+   */
+  id: string | number;
+
+  /**
+   * 站点名称
+   */
+  siteName: string;
+
+  /**
+   * 站点电话
+   */
+  siteTelnum: string;
+
+  /**
+   * 站点地址
+   */
+  siteAddress: string;
+
+  /**
+   * 站点定位
+   */
+  siteGps: string;
+
+  /**
+   * 站点管理员
+   */
+  siteManager: string;
+
+  /**
+   * 站点头像/图片
+   */
+  siteLogo: string;
+
+  /**
+   * 创建时间
+   */
+  createdAt: string;
+
+  /**
+   * 更新时间
+   */
+  updatedAt: string;
+
+}
+
+export interface SiteForm extends BaseEntity {
+  /**
+   * 
+   */
+  id?: string | number;
+
+  /**
+   * 站点名称
+   */
+  siteName?: string;
+
+  /**
+   * 站点电话
+   */
+  siteTelnum?: string;
+
+  /**
+   * 站点地址
+   */
+  siteAddress?: string;
+
+  /**
+   * 站点定位
+   */
+  siteGps?: string;
+
+  /**
+   * 站点管理员
+   */
+  siteManager?: string;
+
+  /**
+   * 站点头像/图片
+   */
+  siteLogo?: string;
+
+  /**
+   * 创建时间
+   */
+  createdAt?: string;
+
+  /**
+   * 更新时间
+   */
+  updatedAt?: string;
+
+}
+
+export interface SiteQuery extends PageQuery {
+
+  /**
+   * 站点名称
+   */
+  siteName?: string;
+
+  /**
+   * 站点电话
+   */
+  siteTelnum?: string;
+
+  /**
+   * 站点地址
+   */
+  siteAddress?: string;
+
+  /**
+   * 站点定位
+   */
+  siteGps?: string;
+
+  /**
+   * 站点管理员
+   */
+  siteManager?: string;
+
+  /**
+   * 站点头像/图片
+   */
+  siteLogo?: string;
+
+  /**
+   * 创建时间
+   */
+  createdAt?: string;
+
+  /**
+   * 更新时间
+   */
+  updatedAt?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 34 - 6
src/components/ImageUpload/index.vue

@@ -47,7 +47,8 @@ import { propTypes } from '@/utils/propTypes';
 import {globalHeaders} from "@/utils/request";
 
 const props = defineProps({
-    modelValue: [String, Object, Array],
+  modelValue: [String, Object, Array],
+    isossid: propTypes.bool.def(true),
     // 图片数量限制
     limit: propTypes.number.def(5),
     // 大小限制(MB)
@@ -89,7 +90,21 @@ watch(() => props.modelValue, async val => {
             const res = await listByIds(val as string)
             list = res.data
         }
-        // 然后将数组转为对象数组
+      if (list == undefined) {
+        fileList.value = val.split(",").map(item => {
+            // 字符串回显处理 如果此处存的是url可直接回显 如果存的是id需要调用接口查出来
+            let itemData;
+            if (typeof item === "string") {
+                itemData = { name: item, url: item };
+            } else {
+                // 此处name使用ossId 防止删除出现重名
+                itemData = { name: item.ossId, url: item.url, ossId: item.ossId };
+            }
+            return itemData;
+        });
+
+      } else {
+         // 然后将数组转为对象数组
         fileList.value = list.map(item => {
             // 字符串回显处理 如果此处存的是url可直接回显 如果存的是id需要调用接口查出来
             let itemData;
@@ -101,6 +116,8 @@ watch(() => props.modelValue, async val => {
             }
             return itemData;
         });
+      }
+
     } else {
         fileList.value = [];
         return [];
@@ -163,8 +180,11 @@ const handleUploadSuccess = (res: any, file: UploadFile) => {
 const handleDelete = (file: UploadFile): boolean => {
     const findex = fileList.value.map(f => f.name).indexOf(file.name);
     if (findex > -1 && uploadList.value.length === number.value) {
-        let ossId = fileList.value[findex].ossId;
+      let ossId = fileList.value[findex].ossId;
+      if (props.isossid) {
         delOss(ossId);
+      }
+
         fileList.value.splice(findex, 1);
         emit("update:modelValue", listToString(fileList.value));
         return false;
@@ -199,11 +219,19 @@ const handlePictureCardPreview = (file: any) => {
 const listToString = (list: any[], separator?: string) => {
     let strs = "";
     separator = separator || ",";
-    for (let i in list) {
-        if (undefined !== list[i].ossId && list[i].url.indexOf("blob:") !== 0) {
-            strs += list[i].ossId + separator;
+  for (let i in list) {
+    if (props.isossid) {
+
+      if (undefined !== list[i].ossId && list[i].url.indexOf("blob:") !== 0) {
+        strs += list[i].ossId + separator;
+      }
+    } else {
+
+        if (undefined !== list[i].url && list[i].url.indexOf("blob:") !== 0) {
+            strs += list[i].url + separator;
         }
     }
+    }
     return strs != "" ? strs.substring(0, strs.length - 1) : "";
 }
 </script>

+ 4 - 4
src/layout/components/Navbar.vue

@@ -25,7 +25,7 @@
           </div>
         </el-tooltip>
         <!-- 消息 -->
-        <el-tooltip :content="$t('navbar.message')" effect="dark" placement="bottom">
+        <el-tooltip :content="'消息'" effect="dark" placement="bottom">
           <div>
             <el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false">
               <template #reference>
@@ -68,13 +68,13 @@
           <template #dropdown>
             <el-dropdown-menu>
               <router-link to="/user/profile" v-if="!dynamic">
-                <el-dropdown-item>{{ $t('navbar.personalCenter') }}</el-dropdown-item>
+                <el-dropdown-item>{{ '个人中心' }}</el-dropdown-item>
               </router-link>
               <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
-                <span>{{ $t('navbar.layoutSetting') }}</span>
+                <span>{{ '布局' }}</span>
               </el-dropdown-item>
               <el-dropdown-item divided command="logout">
-                <span>{{ $t('navbar.logout') }}</span>
+                <span>{{ '退出' }}</span>
               </el-dropdown-item>
             </el-dropdown-menu>
           </template>

+ 388 - 0
src/views/system/bag/index.vue

@@ -0,0 +1,388 @@
+<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="68px">
+          <el-form-item label="快递公司" prop="bagCompany">
+            <el-input v-model="queryParams.bagCompany" placeholder="请输入快递公司" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="快递单号" prop="bagNumber">
+            <el-input v-model="queryParams.bagNumber" placeholder="请输入快递单号" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="出库时间" prop="bagOutTime">
+            <el-date-picker clearable
+              v-model="queryParams.bagOutTime"
+              type="date"
+              value-format="YYYY-MM-DD"
+              placeholder="请选择出库时间"
+            />
+          </el-form-item>
+          <el-form-item label="货架号" prop="bagLocal">
+            <el-input v-model="queryParams.bagLocal" placeholder="请输入货架号" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="层号" prop="bagLocal2">
+            <el-input v-model="queryParams.bagLocal2" placeholder="请输入层号" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="入库时间,停用" prop="bagInTime">
+            <el-date-picker clearable
+              v-model="queryParams.bagInTime"
+              type="date"
+              value-format="YYYY-MM-DD"
+              placeholder="请选择入库时间,停用"
+            />
+          </el-form-item>
+          <el-form-item label="异常原因,如退件、损坏等" prop="bagReason">
+            <el-input v-model="queryParams.bagReason" placeholder="请输入异常原因,如退件、损坏等" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="所在站点" prop="bagSite">
+            <el-input v-model="queryParams.bagSite" placeholder="请输入所在站点" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="修改时间" prop="updatedAt">
+            <el-date-picker clearable
+              v-model="queryParams.updatedAt"
+              type="date"
+              value-format="YYYY-MM-DD"
+              placeholder="请选择修改时间"
+            />
+          </el-form-item>
+          <el-form-item label="创建时间,入库时间" prop="createdAt">
+            <el-date-picker clearable
+              v-model="queryParams.createdAt"
+              type="date"
+              value-format="YYYY-MM-DD"
+              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>
+          </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>
+          <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="id" align="center" prop="id" v-if="true" />
+        <el-table-column label="快递公司" align="center" prop="bagCompany" />
+        <el-table-column label="快递单号" align="center" prop="bagNumber" />
+        <el-table-column label="出库状态,待取件0,出库1,异常2,异常已处理3" align="center" prop="bagStatus" />
+        <el-table-column label="出库时间" align="center" prop="bagOutTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.bagOutTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="货架号" align="center" prop="bagLocal" />
+        <el-table-column label="层号" align="center" prop="bagLocal2" />
+        <el-table-column label="入库时间,停用" align="center" prop="bagInTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.bagInTime, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="异常原因,如退件、损坏等" align="center" prop="bagReason" />
+        <el-table-column label="所在站点" align="center" prop="bagSite" />
+        <el-table-column label="修改时间" align="center" prop="updatedAt" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.updatedAt, '{y}-{m}-{d}') }}</span>
+          </template>
+        </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>
+          </template>
+        </el-table-column>
+        <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="bagCompany">
+          <el-input v-model="form.bagCompany" placeholder="请输入快递公司" />
+        </el-form-item>
+        <el-form-item label="快递单号" prop="bagNumber">
+          <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>
+        </el-form-item>
+        <el-form-item label="货架号" prop="bagLocal">
+          <el-input v-model="form.bagLocal" placeholder="请输入货架号" />
+        </el-form-item>
+        <el-form-item label="层号" prop="bagLocal2">
+          <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>
+        </el-form-item>
+        <el-form-item label="异常原因,如退件、损坏等" prop="bagReason">
+          <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>
+        </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>
+        </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 } from '@/api/system/bag';
+import { BagVO, BagQuery, BagForm } from '@/api/system/bag/types';
+
+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 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,
+    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" }
+    ]
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询【请填写功能名称】列表 */
+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('system/bag/export', {
+    ...queryParams.value
+  }, `bag_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+});
+</script>

+ 230 - 0
src/views/system/companycode/index.vue

@@ -0,0 +1,230 @@
+<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="68px">
+          <el-form-item label="" prop="ShipperCode">
+            <el-input v-model="queryParams.ShipperCode" placeholder="请输入" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="" prop="Company">
+            <el-input v-model="queryParams.Company" 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:companycode:add']">新增</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:companycode:edit']">修改</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:companycode:remove']">删除</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:companycode:export']">导出</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="companycodeList" @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="ShipperCode" />
+        <el-table-column label="" align="center" prop="Company" />
+        <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:companycode:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="删除" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:companycode: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="companycodeFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="" prop="ShipperCode">
+          <el-input v-model="form.ShipperCode" placeholder="请输入" />
+        </el-form-item>
+        <el-form-item label="" prop="Company">
+          <el-input v-model="form.Company" 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="Companycode" lang="ts">
+import { listCompanycode, getCompanycode, delCompanycode, addCompanycode, updateCompanycode } from '@/api/system/companycode';
+import { CompanycodeVO, CompanycodeQuery, CompanycodeForm } from '@/api/system/companycode/types';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const companycodeList = ref<CompanycodeVO[]>([]);
+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 companycodeFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormData: CompanycodeForm = {
+  id: undefined,
+  ShipperCode: undefined,
+  Company: undefined
+}
+const data = reactive<PageData<CompanycodeForm, CompanycodeQuery>>({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    ShipperCode: undefined,
+    Company: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    ShipperCode: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    Company: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ]
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询【请填写功能名称】列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listCompanycode(queryParams.value);
+  companycodeList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = {...initFormData};
+  companycodeFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: CompanycodeVO[]) => {
+  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?: CompanycodeVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getCompanycode(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改【请填写功能名称】";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  companycodeFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateCompanycode(form.value).finally(() =>  buttonLoading.value = false);
+      } else {
+        await addCompanycode(form.value).finally(() =>  buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: CompanycodeVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delCompanycode(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download('system/companycode/export', {
+    ...queryParams.value
+  }, `companycode_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+});
+</script>

+ 318 - 0
src/views/system/punter/index.vue

@@ -0,0 +1,318 @@
+<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="68px">
+          <el-form-item label="" prop="address">
+            <el-input v-model="queryParams.address" placeholder="请输入" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="" prop="telnumber">
+            <el-input v-model="queryParams.telnumber" placeholder="请输入" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="" prop="createdAt">
+            <el-date-picker clearable
+              v-model="queryParams.createdAt"
+              type="date"
+              value-format="YYYY-MM-DD"
+              placeholder="请选择"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="updatedAt">
+            <el-date-picker clearable
+              v-model="queryParams.updatedAt"
+              type="date"
+              value-format="YYYY-MM-DD"
+              placeholder="请选择"
+            />
+          </el-form-item>
+          <el-form-item label="" prop="puntername">
+            <el-input v-model="queryParams.puntername" placeholder="请输入" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="" prop="notes">
+            <el-input v-model="queryParams.notes" placeholder="请输入" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="" prop="site">
+            <el-input v-model="queryParams.site" 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:punter:add']">新增</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:punter:edit']">修改</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:punter:remove']">删除</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:punter:export']">导出</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="punterList" @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="address" />
+        <el-table-column label="" align="center" prop="telnumber" />
+        <el-table-column label="" align="center" prop="createdAt" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="" align="center" prop="updatedAt" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.updatedAt, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="" align="center" prop="puntername" />
+        <el-table-column label="" align="center" prop="notes" />
+        <el-table-column label="" align="center" prop="site" />
+        <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:punter:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="删除" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:punter: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="punterFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="" prop="address">
+          <el-input v-model="form.address" placeholder="请输入" />
+        </el-form-item>
+        <el-form-item label="" prop="telnumber">
+          <el-input v-model="form.telnumber" placeholder="请输入" />
+        </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>
+        </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>
+        </el-form-item>
+        <el-form-item label="" prop="puntername">
+          <el-input v-model="form.puntername" placeholder="请输入" />
+        </el-form-item>
+        <el-form-item label="" prop="notes">
+          <el-input v-model="form.notes" placeholder="请输入" />
+        </el-form-item>
+        <el-form-item label="" prop="site">
+          <el-input v-model="form.site" 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="Punter" lang="ts">
+import { listPunter, getPunter, delPunter, addPunter, updatePunter } from '@/api/system/punter';
+import { PunterVO, PunterQuery, PunterForm } from '@/api/system/punter/types';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const punterList = ref<PunterVO[]>([]);
+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 punterFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormData: PunterForm = {
+  id: undefined,
+  address: undefined,
+  telnumber: undefined,
+  createdAt: undefined,
+  updatedAt: undefined,
+  puntername: undefined,
+  notes: undefined,
+  site: undefined
+}
+const data = reactive<PageData<PunterForm, PunterQuery>>({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    address: undefined,
+    telnumber: undefined,
+    createdAt: undefined,
+    updatedAt: undefined,
+    puntername: undefined,
+    notes: undefined,
+    site: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    address: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    telnumber: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    createdAt: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    updatedAt: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    puntername: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    notes: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    site: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ]
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询【请填写功能名称】列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listPunter(queryParams.value);
+  punterList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = {...initFormData};
+  punterFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: PunterVO[]) => {
+  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?: PunterVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getPunter(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改【请填写功能名称】";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  punterFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updatePunter(form.value).finally(() =>  buttonLoading.value = false);
+      } else {
+        await addPunter(form.value).finally(() =>  buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: PunterVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delPunter(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download('system/punter/export', {
+    ...queryParams.value
+  }, `punter_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+});
+</script>

+ 331 - 0
src/views/system/site/index.vue

@@ -0,0 +1,331 @@
+<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="68px">
+          <el-form-item label="站点名称" prop="siteName">
+            <el-input v-model="queryParams.siteName" placeholder="请输入站点名称" clearable style="width: 240px" @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="站点电话" prop="siteTelnum">
+            <el-input v-model="queryParams.siteTelnum" 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:site:add']">新增</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:site:edit']">修改</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:site:remove']">删除</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:site:export']">导出</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="siteList" @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="siteName" />
+        <el-table-column label="站点电话" align="center" prop="siteTelnum" />
+        <el-table-column label="站点地址" align="center" prop="siteAddress" />
+        <el-table-column label="站点定位" align="center" prop="siteGps" />
+        <el-table-column label="站点管理员" align="center" prop="siteManager" >
+          <template #default="scope">
+            <div>{{ getuserName(scope) }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="站点头像/图片" align="center" prop="siteLogo" >
+          <template #default="scope">
+            <ImagePreview
+              :width="100"
+              :height="100"
+              :src="scope.row.siteLogo"
+              :preview-src-list="[scope.row.siteLogo]"
+            />
+          </template>
+        </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>
+          </template>
+        </el-table-column>
+        <el-table-column label="更新时间" align="center" prop="updatedAt" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.updatedAt, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <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:site:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="删除" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:site: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="siteFormRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="站点名称" prop="siteName">
+          <el-input v-model="form.siteName" placeholder="请输入站点名称" />
+        </el-form-item>
+        <el-form-item label="站点电话" prop="siteTelnum">
+          <el-input v-model="form.siteTelnum" placeholder="请输入站点电话" />
+        </el-form-item>
+        <el-form-item label="站点地址" prop="siteAddress">
+          <el-input v-model="form.siteAddress" placeholder="请输入站点地址" />
+        </el-form-item>
+        <el-form-item label="站点定位" prop="siteGps">
+          <el-input v-model="form.siteGps" placeholder="请输入站点定位" />
+        </el-form-item>
+        <el-form-item label="站点管理员" prop="siteManager">
+          <el-select v-model="form.siteManager" placeholder="请选择管理员">
+            <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="siteLogo">
+          <ImageUpload v-model="form.siteLogo" :max-size="5" :limit="1" :isossid="false" />
+        </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>
+        </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>
+        </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="Site" lang="ts">
+import { listSite, getSite, delSite, addSite, updateSite } from '@/api/system/site';
+import { listUser } from '@/api/system/user';
+import { SiteVO, SiteQuery, SiteForm } from '@/api/system/site/types';
+import ImagePreview from "@/components/ImagePreview/index.vue";
+import ImageUpload from '@/components/ImageUpload/index.vue';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const siteList = ref<SiteVO[]>([]);
+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 siteFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormData: SiteForm = {
+  id: undefined,
+  siteName: undefined,
+  siteTelnum: undefined,
+  siteAddress: undefined,
+  siteGps: undefined,
+  siteManager: undefined,
+  siteLogo: undefined,
+  createdAt: undefined,
+  updatedAt: undefined
+}
+const data = reactive<PageData<SiteForm, SiteQuery>>({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    siteName: undefined,
+    siteTelnum: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "不能为空", trigger: "blur" }
+    ],
+    siteName: [
+      { required: true, message: "站点名称不能为空", trigger: "blur" }
+    ],
+    siteTelnum: [
+      { required: true, message: "站点电话不能为空", trigger: "blur" }
+    ],
+    siteAddress: [
+      { required: true, message: "站点地址不能为空", trigger: "blur" }
+    ],
+    siteGps: [
+      { required: true, message: "站点定位不能为空", trigger: "blur" }
+    ],
+    siteManager: [
+      { required: true, message: "站点管理员不能为空", trigger: "blur" }
+    ],
+    siteLogo: [
+      { required: true, message: "站点头像/图片不能为空", trigger: "blur" }
+    ],
+    createdAt: [
+      { required: true, message: "创建时间不能为空", trigger: "blur" }
+    ],
+    updatedAt: [
+      { required: true, message: "更新时间不能为空", trigger: "blur" }
+    ]
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询【请填写功能名称】列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listSite(queryParams.value);
+  siteList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+const userList = ref(null);
+const getuserList = async () => {
+  const res = await listUser({"params[roleNames]": "驿站管理员"});
+  userList.value = res.rows.map(i => { i.userId = i.userId + ""; return i; });
+}
+
+const getuserName = (row) => {
+  try {
+    return userList.value.filter(i => i.userId === row.row.siteManager)[0].nickName
+  } catch (e) {
+    return "无效用户"
+  }
+
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = {...initFormData};
+  siteFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: SiteVO[]) => {
+  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?: SiteVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getSite(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改站点";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  siteFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateSite(form.value).finally(() =>  buttonLoading.value = false);
+      } else {
+        await addSite(form.value).finally(() =>  buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: SiteVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除站点编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delSite(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download('system/site/export', {
+    ...queryParams.value
+  }, `site_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+   getuserList();
+  getList();
+
+});
+</script>

+ 2 - 2
vite.config.ts

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