snow 2 tahun lalu
induk
melakukan
3a95695ad3

+ 2 - 2
package.json

@@ -42,8 +42,8 @@
     "@vueuse/core": "^8.7.4",
     "@vueuse/motion": "^2.0.0-beta.12",
     "@vueuse/shared": "^8.7.4",
-    "@wangeditor/editor": "^5.0.1",
-    "@wangeditor/editor-for-vue": "^5.1.10",
+    "@wangeditor/editor": "^5.1.14",
+    "@wangeditor/editor-for-vue": "^5.1.12",
     "animate.css": "^4.1.1",
     "axios": "^0.27.2",
     "china-area-data": "^5.0.1",

+ 2 - 2
pnpm-lock.yaml

@@ -41,8 +41,8 @@ specifiers:
   '@vueuse/core': ^8.7.4
   '@vueuse/motion': ^2.0.0-beta.12
   '@vueuse/shared': ^8.7.4
-  '@wangeditor/editor': ^5.0.1
-  '@wangeditor/editor-for-vue': ^5.1.10
+  '@wangeditor/editor': ^5.1.14
+  '@wangeditor/editor-for-vue': ^5.1.12
   animate.css: ^4.1.1
   autoprefixer: ^10.4.5
   axios: ^0.27.2

+ 3 - 2
src/api/system/updates/index.ts

@@ -10,7 +10,7 @@ interface ResponseType extends Promise<any> {
 }
 // 菜单列表
 export const httpAdd = (data: object): ResponseType => {
-  return http.request("post", `${yewuApi}menuadd`, { data });
+  return http.request("post", `${yewuApi}systemadd`, { data });
 };
 // 菜单列表
 export const httpList = (data: object): ResponseType => {
@@ -18,8 +18,9 @@ export const httpList = (data: object): ResponseType => {
 };
 // 菜单更新
 export const httpUpdate = (data: object): ResponseType => {
-  return http.request("post", `${yewuApi}menusave`, { data });
+  return http.request("post", `${yewuApi}systemedit`, { data });
 };
+
 // 菜单状态
 export const httpStatus = (data: object): ResponseType => {
   return http.request("post", `${yewuApi}menustatus`, { data });

+ 3 - 3
src/api/user.ts

@@ -65,6 +65,6 @@ export const httpSupplierall = (data: object): any => {
   });
 };
 
-// export const searchVague = (data: object) => {
-//   return http.request("post", "/searchVague", { data });
-// };
+export const httpSystemLast = (data: object): any => {
+  return http.request("post", `${yewuApi}systemlast`, { data });
+};

+ 2 - 0
src/components/ReIcon/src/iconifyIconOffline.ts

@@ -42,7 +42,9 @@ import DoubleArrowLeft from "@iconify-icons/ep/d-arrow-left";
 import WarningFilled from "@iconify-icons/ep/warning-filled";
 import Excel from "@iconify-icons/fa-solid/file-excel";
 import Promotion from "@iconify-icons/ep/promotion";
+import BellFilled from "@iconify-icons/ep/bell-filled";
 
+addIcon("bell-filled", BellFilled);
 addIcon("success", Select);
 addIcon("excel", Excel);
 addIcon("promotion", Promotion);

+ 20 - 19
src/layout/components/navbar.vue

@@ -13,12 +13,14 @@ import Company from "../components/company/index.vue";
 import Super from "../components/company/super.vue";
 import { useUserInfo } from "/@/hooks/core/useUser";
 import HelpModal from "./help-modal.vue";
+import SystemNotify from "./system-notify.vue";
 
 const route = useRoute();
 const { push } = useRouter();
 const { isSuperUser, userInfo } = useUserInfo();
 const showBackButton = computed(() => route.path.indexOf("Detail") >= 0);
 const helpModalRef = ref<InstanceType<typeof HelpModal> | null>(null);
+const systemNotifyRef = ref<InstanceType<typeof SystemNotify>>(null);
 
 function routeToList() {
   const { path, query } = route;
@@ -59,8 +61,12 @@ const { logout, toggleSideBar, pureApp, avatarsStyle } = useNav();
 
     <div v-if="pureApp.layout === 'vertical'" class="vertical-header-right">
       <!-- 公司名称筛选 -->
-      <Company v-if="!isSuperUser" />
-      <Super v-else />
+      <Super v-if="isSuperUser" />
+      <Company v-else />
+
+      <p class="bell-icon" @click="() => systemNotifyRef.onDisplay()">
+        <IconifyIconOffline icon="bell-filled" />
+      </p>
 
       <!-- 全屏 -->
       <screenfull id="header-screenfull" v-show="!deviceDetection()" />
@@ -70,31 +76,23 @@ const { logout, toggleSideBar, pureApp, avatarsStyle } = useNav();
         <span class="el-dropdown-link">
           <img v-if="avatars" :src="avatars" :style="avatarsStyle" />
           &nbsp; &nbsp;
-          <p v-if="userInfo.nickname">{{ userInfo.nickname }}</p>
+          <template v-if="userInfo">
+            <p>{{ userInfo.nickname }}</p>
+          </template>
         </span>
         <template #dropdown>
           <el-dropdown-menu class="logout">
             <el-dropdown-item>
               <IconifyIconOffline icon="user" style="margin: 5px" />
-              <span v-if="userInfo.mobile">{{ userInfo.mobile }}</span>
+              <template v-if="userInfo">
+                <span>{{ userInfo.mobile }}</span>
+              </template>
             </el-dropdown-item>
 
             <el-dropdown-item @click="() => helpModalRef.onDisplay()">
               <IconifyIconOffline icon="dict" style="margin: 5px" />
               使用说明
             </el-dropdown-item>
-            <!-- <el-dropdown-item @click="logout">
-              <IconifyIconOffline icon="user" style="margin: 5px" />
-              我的信息
-            </el-dropdown-item>
-            <el-dropdown-item @click="logout">
-              <IconifyIconOffline icon="iphone" style="margin: 5px" />
-              更换手机号
-            </el-dropdown-item>
-            <el-dropdown-item @click="logout">
-              <IconifyIconOffline icon="password" style="margin: 5px" />
-              修改密码
-            </el-dropdown-item> -->
             <el-dropdown-item @click="logout">
               <IconifyIconOffline
                 icon="logout-circle-r-line"
@@ -105,12 +103,10 @@ const { logout, toggleSideBar, pureApp, avatarsStyle } = useNav();
           </el-dropdown-menu>
         </template>
       </el-dropdown>
-      <!-- <span class="el-icon-setting" :title="'打开项目配置'" @click="onPanel">
-        <IconifyIconOffline icon="setting" />
-      </span> -->
     </div>
 
     <HelpModal ref="helpModalRef" />
+    <SystemNotify ref="systemNotifyRef" />
   </div>
 </template>
 
@@ -232,4 +228,9 @@ const { logout, toggleSideBar, pureApp, avatarsStyle } = useNav();
     flex-wrap: wrap;
   }
 }
+
+.bell-icon {
+  margin: 0px 10px;
+  cursor: pointer;
+}
 </style>

+ 97 - 0
src/layout/components/system-notify.vue

@@ -0,0 +1,97 @@
+<script setup lang="ts">
+import { ref, computed, watch } from "vue";
+import { useUserStoreHook } from "/@/store/modules/user";
+import dayjs from "dayjs";
+
+const visible = ref(false);
+
+const systemInfo = computed(() => useUserStoreHook().systemInfo);
+
+const UPDATE_KEY = "update";
+
+function setUpdateCache(updateTime: string) {
+  let _update = localStorage.getItem(UPDATE_KEY);
+  const update: any = JSON.parse(_update || "[]");
+  if (update.includes(updateTime)) return;
+  update.push(updateTime);
+  localStorage.setItem(UPDATE_KEY, JSON.stringify(update));
+}
+
+function isCacheUpdate(updateTime) {
+  let _update: any = localStorage.getItem(UPDATE_KEY);
+  const update: any = JSON.parse(_update || "[]");
+  return update.includes(updateTime);
+}
+
+function systemVer() {
+  const { addtime } = systemInfo.value;
+  if (isCacheUpdate(addtime)) return;
+  const updateTime = dayjs(addtime).format("YYYY-MM-DD");
+  const diff = dayjs(new Date()).diff(updateTime, "day");
+  //小于七天的提示示更新
+  if (diff < 7 && !(diff < 0)) {
+    visible.value = true;
+  }
+}
+
+function systemMsg() {
+  const { addtime } = systemInfo.value;
+  if (isCacheUpdate(addtime)) return;
+  const updateTime = dayjs(addtime).format("YYYY-MM-DD");
+  const diff = dayjs(new Date()).diff(updateTime, "day");
+  //前七天开始提醒更新
+  if (diff > -7 && !(diff > 0)) {
+    visible.value = true;
+  }
+}
+
+watch(
+  () => systemInfo.value,
+  ({ sys_type }) => {
+    if (sys_type === "MSG") return systemMsg();
+    if (sys_type === "VER") return systemVer();
+  },
+  {
+    immediate: true
+  }
+);
+
+defineExpose({
+  onDisplay: () => (visible.value = true)
+});
+</script>
+
+<template>
+  <ElDialog v-model="visible" title="系统公告" center>
+    <ElAlert type="success" center :closable="false">
+      <h1 class="font-bold text-center w-full" style="font-size: 16px">
+        {{ systemInfo.module }}
+      </h1>
+    </ElAlert>
+
+    <div class="my-[20px] p-[10px]">
+      <ElRow>
+        <ElCol :span="12" style="display: flex">
+          <p class="font-bold mr-5 mb-5">版本编号:</p>
+          <p>{{ systemInfo.version }}</p>
+        </ElCol>
+        <ElCol :span="12" style="display: flex">
+          <p class="font-bold mr-5">更新时间:</p>
+          <p>{{ systemInfo.addtime }}</p>
+        </ElCol>
+        <ElCol :span="12" style="display: flex">
+          <p class="font-bold mr-5">更新内容:</p>
+          <p v-html="systemInfo.system" />
+        </ElCol>
+      </ElRow>
+    </div>
+
+    <ElRow>
+      <ElCheckbox
+        label="我已知晓,后续不再提醒"
+        :checked="isCacheUpdate(systemInfo.addtime)"
+        @click="() => setUpdateCache(systemInfo.addtime)"
+      />
+    </ElRow>
+  </ElDialog>
+</template>

+ 2 - 1
src/store/modules/types.ts

@@ -23,7 +23,7 @@ export type appType = {
     basic: Record<string, string> | null;
     pagination: any;
   };
-  companyNo: "";
+  companyNo: string;
 };
 
 export type multiType = {
@@ -52,6 +52,7 @@ export type userType = {
   swithingCompany: boolean;
   info: null | Record<string, string>;
   disabledCompany: boolean;
+  systemInfo: Record<string, string>;
 };
 
 export type resType = {

+ 50 - 41
src/store/modules/user.ts

@@ -13,7 +13,8 @@ import {
   ddDetail,
   refreshToken,
   httpCompany,
-  httpUserInfo
+  httpUserInfo,
+  httpSystemLast
 } from "/@/api/user";
 
 import {
@@ -42,8 +43,9 @@ export const useUserStore = defineStore({
     currentCompany: null,
     isSuperUser: false,
     swithingCompany: false,
-    info: {},
-    disabledCompany: false
+    disabledCompany: false,
+    systemInfo: {},
+    info: {}
   }),
   actions: {
     SET_TOKEN(token) {
@@ -106,13 +108,11 @@ export const useUserStore = defineStore({
     },
     async requesetUserInfo() {
       this.currentCompany = null;
-
       const { code, data } = await httpUserInfo({
         noRela: true
       });
 
       this.info = data;
-
       if (Number(code) === 0) {
         const { role_level } = data;
         this.isSuperUser = role_level === "1";
@@ -136,49 +136,58 @@ export const useUserStore = defineStore({
         throw new Error();
       }
     },
+    async requsetSystemInfo() {
+      const { data, code } = await httpSystemLast({});
+      if (Number(code) === 0) {
+        this.systemInfo = data;
+      } else {
+        throw new Error();
+      }
+    },
     // 获取当前账号菜单数据
     async postMenuList(form) {
       try {
         await this.requesetUserInfo();
-      } catch (err) {
-        window.location.hash = "login";
-      }
+        await this.requsetSystemInfo();
 
-      return new Promise((resolve, reject) => {
-        getAsyncRoutes(form)
-          .then((res: resType) => {
-            const { code, data } = res;
+        return new Promise((resolve, reject) => {
+          getAsyncRoutes(form)
+            .then((res: resType) => {
+              const { code, data } = res;
 
-            const actionList: Array<any> = [];
-            switch (Number(code)) {
-              case 0:
-                data.forEach(e => {
-                  e.child?.forEach(s => {
-                    const item = {
-                      menu_route: s.menu_route,
-                      action: s.action
-                    };
-                    actionList.push(item);
+              const actionList: Array<any> = [];
+              switch (Number(code)) {
+                case 0:
+                  data.forEach(e => {
+                    e.child?.forEach(s => {
+                      const item = {
+                        menu_route: s.menu_route,
+                        action: s.action
+                      };
+                      actionList.push(item);
+                    });
                   });
-                });
-                setAction(JSON.stringify(actionList));
-                resolve(res);
-                break;
-              case 10000:
-                removeMenus();
-                this.disabledCompany = true;
-                reject(10000);
-                return;
-              default:
-                resolve(res);
-                break;
-            }
-            this.disabledCompany = false;
-          })
-          .catch(error => {
-            reject(error);
-          });
-      });
+                  setAction(JSON.stringify(actionList));
+                  resolve(res);
+                  break;
+                case 10000:
+                  removeMenus();
+                  this.disabledCompany = true;
+                  reject(10000);
+                  return;
+                default:
+                  resolve(res);
+                  break;
+              }
+              this.disabledCompany = false;
+            })
+            .catch(error => {
+              reject(error);
+            });
+        });
+      } catch (err) {
+        window.location.hash = "login";
+      }
     },
     // 登出 清空缓存
     logOut() {

+ 1 - 0
src/views/InvoiceSales/capitalClaim/components/basic-claim/sales-modal.vue

@@ -135,6 +135,7 @@ onMounted(() => reuquestSalelist());
         :label="col.label"
         :key="index"
         :width="col.width + 'px'"
+        :fixed="col.fixed"
         :type="col.type"
         show-overflow-tooltip
       >

+ 63 - 48
src/views/InvoiceSales/capitalClaim/config/configs.ts

@@ -3,25 +3,32 @@ export const order_columns = [
     label: "订单编号",
     prop: "sequenceNo",
     minWidth: 180,
-    align: "left"
+    align: "left",
+    fixed: "left"
   },
   {
-    label: "购买方公司",
+    label: "客户名称",
     prop: "customerName",
     minWidth: 180,
     align: "left"
   },
   {
-    label: "销售方公司",
-    prop: "companyName",
+    label: "订单总金额",
+    prop: "totalPrice",
     minWidth: 180,
     align: "left"
   },
   {
-    label: "客户名称",
-    prop: "customerName",
-    minWidth: 180,
-    align: "left"
+    prop: "apay_fee",
+    label: "已付款"
+  },
+  {
+    prop: "pay_fee",
+    label: "付款中"
+  },
+  {
+    prop: "wpay_fee",
+    label: "未付款"
   },
   {
     label: "商品名称",
@@ -30,22 +37,28 @@ export const order_columns = [
     align: "left"
   },
   {
-    label: "订单总金额",
-    prop: "totalPrice",
+    label: "平台名称",
+    prop: "platName",
     minWidth: 180,
     align: "left"
   },
   {
-    prop: "apay_fee",
-    label: "已付款"
+    label: "销售员",
+    prop: "saler",
+    minWidth: 180,
+    align: "left"
   },
   {
-    prop: "pay_fee",
-    label: "付款中"
+    label: "购买方公司",
+    prop: "customerName",
+    minWidth: 180,
+    align: "left"
   },
   {
-    prop: "wpay_fee",
-    label: "未付款"
+    label: "销售方公司",
+    prop: "companyName",
+    minWidth: 180,
+    align: "left"
   },
   {
     label: "此次认领",
@@ -148,22 +161,37 @@ export const status_options = [
 
 export const sale_columns = [
   {
-    type: "selection"
+    type: "selection",
+    fixed: "left"
   },
   {
     field: "sequenceNo",
     label: "订单编号",
-    width: 140
+    width: 140,
+    fixed: "left"
   },
   {
-    field: "companyNo",
-    label: "业务公司编号",
-    width: 140
+    label: "客户名称",
+    field: "customerName",
+    width: 180,
+    align: "left"
   },
   {
-    field: "goodNo",
-    label: "商品编号",
-    width: 140
+    field: "totalPrice",
+    width: 100,
+    label: "订单总金额"
+  },
+  {
+    field: "apay_fee",
+    label: "已付款"
+  },
+  {
+    field: "pay_fee",
+    label: "付款中"
+  },
+  {
+    field: "wpay_fee",
+    label: "未付款"
   },
   {
     field: "goodName",
@@ -171,15 +199,9 @@ export const sale_columns = [
     width: 140
   },
   {
-    field: "companyName",
-    width: 120,
-    label: "业务公司名称"
-  },
-  {
-    label: "客户名称",
-    field: "customerName",
-    width: 180,
-    align: "left"
+    field: "goodNo",
+    label: "商品编号",
+    width: 140
   },
   {
     label: "平台名称",
@@ -188,9 +210,8 @@ export const sale_columns = [
     align: "left"
   },
   {
-    field: "totalPrice",
-    width: 100,
-    label: "订单销售金额"
+    field: "ownerName",
+    label: "销售员"
   },
   {
     field: "qrdType",
@@ -201,20 +222,14 @@ export const sale_columns = [
     label: "订单来源"
   },
   {
-    field: "apay_fee",
-    label: "已付款"
-  },
-  {
-    field: "pay_fee",
-    label: "付款中"
-  },
-  {
-    field: "wpay_fee",
-    label: "未付款"
+    field: "companyNo",
+    label: "业务公司编号",
+    width: 140
   },
   {
-    field: "ownerName",
-    label: "销售员"
+    field: "companyName",
+    width: 120,
+    label: "业务公司名称"
   }
 ];
 

+ 39 - 68
src/views/InvoiceSales/invoiceApply/components/add-edit-form/columns.tsx

@@ -11,7 +11,8 @@ export function useColumns() {
       label: "销售订单编号",
       prop: "sequenceNo",
       minWidth: 160,
-      showOverflowTooltip: true
+      showOverflowTooltip: true,
+      fixed: "left"
     },
 
     // {
@@ -20,7 +21,11 @@ export function useColumns() {
     //   minWidth: 160,
     //   showOverflowTooltip: true
     // },
-
+    {
+      label: "po编号",
+      prop: "poCode",
+      minWidth: 190
+    },
     {
       label: "商品编码",
       prop: "goodNo",
@@ -28,9 +33,10 @@ export function useColumns() {
       showOverflowTooltip: true
     },
     {
-      label: "po编号",
-      prop: "poCode",
-      minWidth: 190
+      label: "商品名称",
+      prop: "goodName",
+      minWidth: 160,
+      showOverflowTooltip: true
     },
     {
       label: "客户编号",
@@ -44,49 +50,40 @@ export function useColumns() {
       minWidth: 160,
       showOverflowTooltip: true
     },
-
-    // {
-    //   label: "商品名称",
-    //   prop: "goodName",
-    //   minWidth: 160,
-    //   showOverflowTooltip: true
-    // },
-    // {
-    //   label: "商品单价",
-    //   prop: "goodPrice",
-    //   minWidth: 160,
-    //   showOverflowTooltip: true
-    // },
-    // {
-    //   label: "数量",
-    //   prop: "goodNum",
-    //   minWidth: 160,
-    //   showOverflowTooltip: true
-    // },
-    // {
-    //   label: "分类",
-    //   prop: "goodNum",
-    //   minWidth: 160,
-    //   showOverflowTooltip: true,
-    //   cellRenderer({ row }) {
-    //     return row.catInfo.map(({ cat_name }) => cat_name)?.join("/");
-    //   }
-    // },
-    // {
-    //   label: "税率",
-    //   prop: "tax",
-    //   minWidth: 160,
-    //   showOverflowTooltip: true,
-    //   cellRenderer({ row }) {
-    //     return row.tax + "%";
-    //   }
-    // },
     {
       label: "订单总金额",
       prop: "totalPrice",
       minWidth: 110,
       showOverflowTooltip: true
     },
+    {
+      label: "商品数量",
+      prop: "goodNum",
+      minWidth: 160,
+      showOverflowTooltip: true
+    },
+    {
+      label: "未开票数量",
+      prop: "winv_num"
+    },
+    {
+      label: "已开票金额",
+      prop: "ainv_fee",
+      minWidth: 110,
+      showOverflowTooltip: true
+    },
+    {
+      label: "开票中金额",
+      prop: "inv_fee",
+      minWidth: 110,
+      showOverflowTooltip: true
+    },
+    {
+      label: "未开票金额",
+      prop: "winv_fee",
+      minWidth: 110,
+      showOverflowTooltip: true
+    },
     {
       label: "发货状态",
       prop: "sendStatus",
@@ -111,32 +108,6 @@ export function useColumns() {
         </el-tag>
       )
     },
-    {
-      label: "商品数量",
-      prop: "goodNum"
-    },
-    {
-      label: "未开票数量",
-      prop: "winv_num"
-    },
-    {
-      label: "已开票",
-      prop: "ainv_fee",
-      minWidth: 110,
-      showOverflowTooltip: true
-    },
-    {
-      label: "开票中",
-      prop: "inv_fee",
-      minWidth: 110,
-      showOverflowTooltip: true
-    },
-    {
-      label: "未开票",
-      prop: "winv_fee",
-      minWidth: 110,
-      showOverflowTooltip: true
-    },
     {
       label: "业务员",
       prop: "ownerName",

+ 1 - 1
src/views/InvoiceSales/invoiceApply/components/add-edit-form/order-dialog.vue

@@ -2,7 +2,7 @@
 import { reactive, ref, unref } from "vue";
 import { httpOrderList } from "/@/api/InvoiceSales/invoiceApply";
 import { PageSearch, usePageSearch } from "/@/components/PageSearch";
-import searchFormConfig from "./../../config/search.config";
+import searchFormConfig from "./search.config";
 import { responseHandle } from "/@/utils/responseHandle";
 import { useNav } from "/@/layout/hooks/nav";
 import { ElMessage } from "element-plus";

+ 27 - 0
src/views/InvoiceSales/invoiceApply/components/add-edit-form/search.config.ts

@@ -0,0 +1,27 @@
+import { FormConfig } from "/@/components/PageSearch";
+import { INV_OPEN_STATUS } from "/@/utils/details/inv-open";
+
+const searchFormConfig: FormConfig = {
+  colLayout: { span: 8 },
+  formItems: [
+    {
+      field: "customer",
+      type: "input",
+      placeholder: "客户名称"
+    },
+    {
+      field: "sequenceNo",
+      type: "input",
+      placeholder: "销售单编号"
+    },
+    {
+      field: "status",
+      type: "select",
+      placeholder: "状态",
+      span: 4,
+      options: INV_OPEN_STATUS
+    }
+  ]
+};
+
+export default searchFormConfig;

+ 21 - 0
src/views/InvoiceSales/invoiceApply/config/search.config.ts

@@ -4,17 +4,38 @@ import { INV_OPEN_STATUS } from "/@/utils/details/inv-open";
 const searchFormConfig: FormConfig = {
   colLayout: { span: 8 },
   formItems: [
+    {
+      field: "invNo",
+      type: "input",
+      placeholder: "发票申请编号"
+    },
     {
       field: "buyer_name",
       type: "input",
       placeholder: "客户名称"
     },
+    {
+      field: "apply_name",
+      type: "input",
+      placeholder: "申请人"
+    },
     {
       field: "status",
       type: "select",
       placeholder: "状态",
       span: 4,
       options: INV_OPEN_STATUS
+    },
+    {
+      field: "timer",
+      type: "date_picker",
+      otherOptions: {
+        type: "daterange",
+        startProp: "start",
+        endProp: "end",
+        startPlaceholder: "申请开始时间",
+        endPlaceholder: "申请结束时间"
+      }
     }
   ]
 };

+ 1 - 1
src/views/InvoiceSales/refund/components/approval-pending.vue

@@ -52,7 +52,7 @@ const handlePaymentReceipt = () => {
 };
 
 watchEffect(() => {
-  rules.remark[0].required = String(formData.status) !== "2";
+  rules.remark[0].required = String(formData.status) !== "1";
 });
 </script>
 

+ 3 - 1
src/views/InvoiceSales/refund/config/_rules.ts

@@ -1,4 +1,6 @@
 export const createRules = {
   logNo: [{ required: true, trigger: "change", message: "请选择一笔资金" }],
-  type: [{ required: true, trigger: "change", message: "请选择申请类型" }]
+  return_reason: [
+    { required: true, trigger: "change", message: "请输入退款原因" }
+  ]
 };

+ 2 - 0
src/views/InvoiceSales/returnTicket/components/approval-pending.vue

@@ -126,6 +126,8 @@ watchEffect(() => {
   outMonthAndPaper.value =
     (isOutMonth && invType === "normal") || invType === "special";
 
+  rules.remark[0].required = formData.status === "3";
+
   //校验码是否必填
   rules.checkCode[0].required =
     invType === "special_electronic" || invType === "electronic";

+ 1 - 0
src/views/purchase/porder/config/search.config.ts

@@ -15,6 +15,7 @@ const searchFormConfig: FormConfig = {
       otherOptions: {
         inputGroupOptions: [
           { value: "sequenceNo", label: "采购单编号" },
+          { value: "qrdCode", label: "确认单编号" },
           { value: "supplierNo", label: "卖出方公司编号" },
           { value: "supplierName", label: "卖出方公司名称" },
           { value: "qrdCode", label: "订单编号" },

+ 1 - 1
src/views/supply/orderRecord/index.vue

@@ -16,7 +16,7 @@ const baseUrl = "/supply/supplyOrderRecordDetail";
 const { push } = useRouter();
 const selectlist = ref<any[]>([]);
 
-//  { code: "031", name: "下载批量开票模板" },
+//{ code: "031", name: "下载批量开票模板" },
 const { hasPermissionWithCode } = usePermission(PageName);
 
 const hooks: PageHooks = {

+ 2 - 2
src/views/supply/porder/config/search.config.ts

@@ -13,8 +13,8 @@ const searchFormConfig: FormConfig = {
       type: "input_group",
       otherOptions: {
         inputGroupOptions: [
-          { value: "qrdCode", label: "订单编号" },
-          { value: "sequenceNo", label: "销售订单编号" },
+          { value: "sequenceNo", label: "采购单编号" },
+          { value: "qrdCode", label: "确认单编号" },
           { value: "companyNo", label: "买入方公司编号" },
           { value: "companyName", label: "买入方公司名称" },
           // { value: "bkCode", label: "备库单号" },

+ 2 - 2
src/views/supply/ticketReturn/index.vue

@@ -17,8 +17,8 @@ const PageName = "supplyTicketReturn";
 const baseUrl = "/supply/supplyTicketReturnDetail";
 const invStatus = ["3", "4", "5", "6", "9", "10", "12"];
 
-//   { code: "032", name: "导出对账开票数据" },
-//   { code: "033", name: "批量创建开票数据" }
+// { code: "032", name: "导出对账开票数据" },
+// { code: "033", name: "批量创建开票数据" }
 const { hasPermissionWithCode } = usePermission(PageName);
 const { isSuperUser } = useUserInfo();
 

+ 158 - 3
src/views/system/updates/components/update-modal.vue

@@ -1,11 +1,166 @@
 <script setup lang="ts">
-import { ref } from "vue";
+import "@wangeditor/editor/dist/css/style.css"; // 引入 css
+import { onBeforeUnmount, ref, shallowRef, nextTick } from "vue";
+import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
+import { ElForm } from "element-plus";
+
+const emit = defineEmits(["create", "update"]);
+
+defineProps<{
+  loading: boolean;
+}>();
+
+const mode = "default";
+const type = ref<any>("create");
 const visible = ref(false);
+const editorRef = shallowRef();
+const formRef = ref<InstanceType<typeof ElForm>>();
+const id = ref("");
+
+const editorConfig = { placeholder: "请输入内容..." };
+const formData = ref({
+  module: "",
+  system: "",
+  sys_type: "",
+  version: "",
+  addtime: ""
+});
+
+const createRequiredRule = message => ({
+  message,
+  required: true,
+  trigger: "change"
+});
+
+const rules = {
+  module: [createRequiredRule("标题不能为空")],
+  system: [createRequiredRule("内容不能为空")],
+  sys_type: [createRequiredRule("请选择一个类型")],
+  version: [createRequiredRule("版本号不能为空")],
+  time: [createRequiredRule("时间不能为空")]
+};
+
+onBeforeUnmount(() => {
+  const editor = editorRef.value;
+  if (editor == null) return;
+  editor.destroy();
+});
+
+const handleCreated = editor => {
+  editorRef.value = editor;
+};
+
+function handleClose() {
+  formData.value = {
+    module: "",
+    system: "",
+    sys_type: "",
+    version: "",
+    addtime: ""
+  };
+
+  nextTick(() => {
+    Object.keys(formData.value).forEach(key =>
+      formRef.value.clearValidate(key)
+    );
+  });
+}
+
+function handleConfirm() {
+  formRef.value.validate(isValid => {
+    isValid &&
+      emit(type.value, {
+        ...formData.value,
+        ...(type.value === "update" ? { id: id.value } : {})
+      });
+  });
+}
 
 defineExpose({
-  onDisplay: () => (visible.value = true)
+  onDisplay: (_data?: any) => {
+    visible.value = true;
+    type.value = _data ? "update" : "create";
+    const { module, system, sys_type, version, addtime, id: _id } = _data;
+    id.value = _id;
+    formData.value = {
+      module,
+      system,
+      sys_type,
+      version,
+      addtime
+    };
+  },
+  onHidden: () => (visible.value = false)
 });
 </script>
 <template>
-  <ElDialog v-model="visible" />
+  <ElDialog
+    v-model="visible"
+    :title="type === 'create' ? '添加版本信息' : '修改版本信息'"
+    @close="handleClose"
+    width="1040px"
+    destroy-on-close
+    center
+    top="10vh"
+  >
+    <ElForm label-width="80px" :model="formData" :rules="rules" ref="formRef">
+      <ElRow :gutter="10">
+        <ElCol :span="12">
+          <ElFormItem label="类型" prop="sys_type">
+            <ElSelect style="width: 100%" v-model="formData.sys_type">
+              <ElOption value="MSG" label="维护公告" />
+              <ElOption value="VER" label="版本信息" />
+            </ElSelect>
+          </ElFormItem>
+        </ElCol>
+        <ElCol :span="12">
+          <ElFormItem label="版本号" prop="version">
+            <ElInput placeholder="版本号" v-model="formData.version" />
+          </ElFormItem>
+        </ElCol>
+      </ElRow>
+      <ElRow :gutter="10">
+        <ElCol :span="12">
+          <ElFormItem label="标题" prop="module">
+            <ElInput placeholder="标题" v-model="formData.module" />
+          </ElFormItem>
+        </ElCol>
+        <ElCol :span="12">
+          <ElFormItem label="时间">
+            <ElDatePicker
+              value-format="YYYY-MM-DD HH:mm:ss"
+              v-model="formData.addtime"
+              type="datetime"
+              style="width: 100%"
+              placeholder="时间"
+            />
+          </ElFormItem>
+        </ElCol>
+      </ElRow>
+      <ElFormItem label="内容" prop="system">
+        <div style="border: 1px solid #ccc">
+          <Toolbar
+            style="border-bottom: 1px solid #ccc"
+            :editor="editorRef"
+            :mode="mode"
+          />
+          <Editor
+            style="height: 400px; overflow-y: hidden"
+            v-model="formData.system"
+            :defaultConfig="editorConfig"
+            :mode="mode"
+            @onCreated="handleCreated"
+          />
+        </div>
+      </ElFormItem>
+
+      <ElFormItem>
+        <div class="flex w-full justify-end">
+          <ElButton type="primary" @click="handleConfirm" :loading="loading"
+            >保存</ElButton
+          >
+        </div>
+      </ElFormItem>
+    </ElForm>
+  </ElDialog>
 </template>

+ 1 - 0
src/views/system/updates/config/content.config.ts

@@ -33,6 +33,7 @@ const contentConfig: ContentConfig = {
   title: "版本更新",
   columns,
   isTree: true,
+  notPreview: true,
   apis: {
     httpList,
     httpDelete,

+ 31 - 3
src/views/system/updates/index.vue

@@ -2,17 +2,36 @@
 import { ref } from "vue";
 import UpdateModal from "./components/update-modal.vue";
 import contentConfig from "./config/content.config";
+import { httpUpdate, httpAdd } from "/@/api/system/updates";
+import { useAsync } from "/@/hooks/core/useAsync";
 import { PageEvents } from "/@/hooks/page";
 
 const PageName = "updates";
 
 const updateModalRef = ref<InstanceType<typeof UpdateModal> | null>(null);
+const pageContenrRef = ref<any>();
+
+const { run: create, loading: _loading } = useAsync({
+  success: () => {
+    pageContenrRef.value.onSearch();
+    updateModalRef.value.onHidden();
+  }
+});
+const { run: update, loading } = useAsync({
+  success: () => {
+    pageContenrRef.value.onSearch();
+    updateModalRef.value.onHidden();
+  }
+});
+
+const handleCreate = _data => create(httpAdd(_data));
+const handleUpdate = _data => update(httpUpdate(_data));
 
 const events: PageEvents = {
   content: {
     preview: () => updateModalRef.value.onDisplay(),
     create: () => updateModalRef.value.onDisplay(),
-    update: () => updateModalRef.value.onDisplay()
+    update: row => updateModalRef.value.onDisplay(row)
   }
 };
 
@@ -24,7 +43,11 @@ function getUpdateContent(content: string) {
 
 <template>
   <PageAuth :pageName="PageName">
-    <PageContainer :events="events" :contentConfig="contentConfig">
+    <PageContainer
+      :events="events"
+      :contentConfig="contentConfig"
+      :get-content-ref="ref => (pageContenrRef = ref)"
+    >
       <template #expand="row">
         <div class="ml-[40px]">
           <h1 class="font-bold ml-[10px]">更新内容</h1>
@@ -41,6 +64,11 @@ function getUpdateContent(content: string) {
       </template>
     </PageContainer>
 
-    <UpdateModal ref="updateModalRef" />
+    <UpdateModal
+      ref="updateModalRef"
+      :loading="loading || _loading"
+      @create="handleCreate"
+      @update="handleUpdate"
+    />
   </PageAuth>
 </template>