曹睿
12 小时以前 f36f2f20bfb06dc3ca1b69c8a6d260d09d7d70ba
feat: 新增设备报修模块。
已修改14个文件
已添加6个文件
910 ■■■■ 文件已修改
src/api/equipmentManagement/ledger.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/equipmentManagement/repair.js 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/procurementManagement/paymentLedger.js 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Settings/index.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/settings.js 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/ledger/Modal.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Form/MaintainForm.vue 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Form/RepairForm.vue 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Modal/MaintainModal.vue 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Modal/RepairModal.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/index.vue 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/invoiceEntry/components/ExpandTable.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/invoiceEntry/components/Modal.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/invoiceEntry/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/paymentEntry/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/paymentHistory/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/paymentLedger/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementInvoiceLedger/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/invoiceRegistration/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/receiptPaymentHistory/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/equipmentManagement/ledger.js
@@ -35,3 +35,10 @@
    method: "delete",
  });
};
export const getDeviceLedger = () => {
  return request({
    url: "/device/ledger/getDeviceLedger",
    method: "get",
  });
};
src/api/equipmentManagement/repair.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
import request from "@/utils/request";
/**
 * @desc è®¾å¤‡æŠ¥ä¿®åˆ—表
 * @param {分页查询} params
 * @returns
 */
export const getRepairPage = (params) => {
  return request({
    url: "/device/repair/page",
    method: "get",
    params,
  });
};
/**
 * @desc æ–°å¢žæŠ¥ä¿®
 * @param {报修参数} data
 * @returns
 */
export const addRepair = (data) => {
  return request({
    url: "/device/repair",
    method: "post",
    data,
  });
};
/**
 * @desc ç¼–辑报修
 * @param {报修参数} data
 * @returns
 */
export const editRepair = (data) => {
  return request({
    url: "/device/repair",
    method: "put",
    data,
  });
};
/**
 * @desc æ ¹æ®id查询一条报修
 * @param {报修id} id
 * @returns
 */
export const getRepairById = (id) => {
  return request({
    url: `/device/repair/${id}`,
    method: "get",
  });
};
/**
 * @desc åˆ é™¤æŠ¥ä¿®
 * @param {编号} ids
 * @returns
 */
export const delRepair = (ids) => {
  return request({
    url: `/device/repair/${ids}`,
    method: "delete",
  });
};
export const addMaintain = (data) => {
  return request({
    url: `/device/repair/repair`,
    method: "post",
    data,
  });
};
src/api/procurementManagement/paymentLedger.js
@@ -1,19 +1,19 @@
// é‡‡è´­å°è´¦é¡µé¢æŽ¥å£
import request from '@/utils/request'
import request from "@/utils/request";
// åˆ†é¡µæŸ¥è¯¢
export function paymentLedgerList(query) {
    return request({
        url: '/purchase/paymentRegistration/paymentLedgerList',
        method: 'get',
        params: query
    })
  return request({
    url: "/purchase/paymentRegistration/paymentLedgerList",
    method: "get",
    params: query,
  });
}
// åˆ†é¡µæŸ¥è¯¢
export function paymentRecordList(supplierId) {
    return request({
        url: '/purchase/paymentRegistration/getPaymentRecordList/'+ supplierId,
        method: 'get'
    })
  return request({
    url: "/purchase/paymentRegistration/getPaymentRecordList/" + supplierId,
    method: "get",
  });
}
src/layout/components/Settings/index.vue
@@ -4,22 +4,58 @@
      <h3 class="drawer-title">主题风格设置</h3>
    </div>
    <div class="setting-drawer-block-checbox">
      <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
      <div
        class="setting-drawer-block-checbox-item"
        @click="handleTheme('theme-dark')"
      >
        <img src="@/assets/images/dark.svg" alt="dark" />
        <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
        <div
          v-if="sideTheme === 'theme-dark'"
          class="setting-drawer-block-checbox-selectIcon"
          style="display: block"
        >
          <i aria-label="图标: check" class="anticon anticon-check">
            <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
              <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
            <svg
              viewBox="64 64 896 896"
              data-icon="check"
              width="1em"
              height="1em"
              :fill="theme"
              aria-hidden="true"
              focusable="false"
              class
            >
              <path
                d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
              />
            </svg>
          </i>
        </div>
      </div>
      <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
      <div
        class="setting-drawer-block-checbox-item"
        @click="handleTheme('theme-light')"
      >
        <img src="@/assets/images/light.svg" alt="light" />
        <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
        <div
          v-if="sideTheme === 'theme-light'"
          class="setting-drawer-block-checbox-selectIcon"
          style="display: block"
        >
          <i aria-label="图标: check" class="anticon anticon-check">
            <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
              <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
            <svg
              viewBox="64 64 896 896"
              data-icon="check"
              width="1em"
              height="1em"
              :fill="theme"
              aria-hidden="true"
              focusable="false"
              class
            >
              <path
                d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
              />
            </svg>
          </i>
        </div>
@@ -28,7 +64,11 @@
    <div class="drawer-item">
      <span>主题颜色</span>
      <span class="comp-style">
        <el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange"/>
        <el-color-picker
          v-model="theme"
          :predefine="predefineColors"
          @change="themeChange"
        />
      </span>
    </div>
    <el-divider />
@@ -38,7 +78,11 @@
    <div class="drawer-item">
      <span>开启 TopNav</span>
      <span class="comp-style">
        <el-switch v-model="settingsStore.topNav" @change="topNavChange" class="drawer-switch" />
        <el-switch
          v-model="settingsStore.topNav"
          @change="topNavChange"
          class="drawer-switch"
        />
      </span>
    </div>
@@ -72,81 +116,93 @@
    <el-divider />
    <el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">保存配置</el-button>
    <el-button type="primary" plain icon="DocumentAdd" @click="saveSetting"
      >保存配置</el-button
    >
    <el-button plain icon="Refresh" @click="resetSetting">重置配置</el-button>
  </el-drawer>
</template>
<script setup>
import variables from '@/assets/styles/variables.module.scss'
import axios from 'axios'
import { ElLoading, ElMessage } from 'element-plus'
import { useDynamicTitle } from '@/utils/dynamicTitle'
import useAppStore from '@/store/modules/app'
import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission'
import { handleThemeStyle } from '@/utils/theme'
import variables from "@/assets/styles/variables.module.scss";
import axios from "axios";
import { ElLoading, ElMessage } from "element-plus";
import { useDynamicTitle } from "@/utils/dynamicTitle";
import useAppStore from "@/store/modules/app";
import useSettingsStore from "@/store/modules/settings";
import usePermissionStore from "@/store/modules/permission";
import { handleThemeStyle } from "@/utils/theme";
const { proxy } = getCurrentInstance()
const appStore = useAppStore()
const settingsStore = useSettingsStore()
const permissionStore = usePermissionStore()
const showSettings = ref(false)
const theme = ref(settingsStore.theme)
const sideTheme = ref(settingsStore.sideTheme)
const storeSettings = computed(() => settingsStore)
const predefineColors = ref(["#800020", "#81D8D0", "#E85827", "#008C8C", "#002FA7", "#F9DC24", "#B05923", "#003153", "#8F4B28", "#4C0009"])
const { proxy } = getCurrentInstance();
const appStore = useAppStore();
const settingsStore = useSettingsStore();
const permissionStore = usePermissionStore();
const showSettings = ref(false);
const theme = ref(settingsStore.theme);
const sideTheme = ref(settingsStore.sideTheme);
const storeSettings = computed(() => settingsStore);
const predefineColors = ref([
  "#002fa7",
  "#81D8D0",
  "#E85827",
  "#008C8C",
  "#002FA7",
  "#F9DC24",
  "#B05923",
  "#003153",
  "#8F4B28",
  "#4C0009",
]);
/** æ˜¯å¦éœ€è¦topnav */
function topNavChange(val) {
  if (!val) {
    appStore.toggleSideBarHide(false)
    permissionStore.setSidebarRouters(permissionStore.defaultRoutes)
    appStore.toggleSideBarHide(false);
    permissionStore.setSidebarRouters(permissionStore.defaultRoutes);
  }
}
function themeChange(val) {
  settingsStore.theme = val
  handleThemeStyle(val)
  settingsStore.theme = val;
  handleThemeStyle(val);
}
function handleTheme(val) {
  settingsStore.sideTheme = val
  sideTheme.value = val
  settingsStore.sideTheme = val;
  sideTheme.value = val;
}
function saveSetting() {
  proxy.$modal.loading("正在保存到本地,请稍候...")
  proxy.$modal.loading("正在保存到本地,请稍候...");
  let layoutSetting = {
    "topNav": storeSettings.value.topNav,
    "tagsView": storeSettings.value.tagsView,
    "fixedHeader": storeSettings.value.fixedHeader,
    "sidebarLogo": storeSettings.value.sidebarLogo,
    "dynamicTitle": storeSettings.value.dynamicTitle,
    "sideTheme": storeSettings.value.sideTheme,
    "theme": storeSettings.value.theme
  }
  localStorage.setItem("layout-setting", JSON.stringify(layoutSetting))
  setTimeout(proxy.$modal.closeLoading(), 1000)
    topNav: storeSettings.value.topNav,
    tagsView: storeSettings.value.tagsView,
    fixedHeader: storeSettings.value.fixedHeader,
    sidebarLogo: storeSettings.value.sidebarLogo,
    dynamicTitle: storeSettings.value.dynamicTitle,
    sideTheme: storeSettings.value.sideTheme,
    theme: storeSettings.value.theme,
  };
  localStorage.setItem("layout-setting", JSON.stringify(layoutSetting));
  setTimeout(proxy.$modal.closeLoading(), 1000);
}
function resetSetting() {
  proxy.$modal.loading("正在清除设置缓存并刷新,请稍候...")
  localStorage.removeItem("layout-setting")
  setTimeout("window.location.reload()", 1000)
  proxy.$modal.loading("正在清除设置缓存并刷新,请稍候...");
  localStorage.removeItem("layout-setting");
  setTimeout("window.location.reload()", 1000);
}
function openSetting() {
  showSettings.value = true
  showSettings.value = true;
}
defineExpose({
  openSetting
})
  openSetting,
});
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
.setting-drawer-title {
  margin-bottom: 12px;
  color: var(--el-text-color-primary, rgba(0, 0, 0, 0.85));
@@ -201,4 +257,4 @@
    margin: -3px 8px 0px 0px;
  }
}
</style>
</style>
src/store/modules/settings.js
@@ -1,48 +1,67 @@
import defaultSettings from '@/settings'
import { useDark, useToggle } from '@vueuse/core'
import { useDynamicTitle } from '@/utils/dynamicTitle'
import defaultSettings from "@/settings";
import { useDark, useToggle } from "@vueuse/core";
import { useDynamicTitle } from "@/utils/dynamicTitle";
const isDark = useDark()
const toggleDark = useToggle(isDark)
const isDark = useDark();
const toggleDark = useToggle(isDark);
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
const {
  sideTheme,
  showSettings,
  topNav,
  tagsView,
  fixedHeader,
  sidebarLogo,
  dynamicTitle,
} = defaultSettings;
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const storageSetting = JSON.parse(localStorage.getItem("layout-setting")) || "";
const useSettingsStore = defineStore(
  'settings',
  {
    state: () => ({
      title: '',
      theme: storageSetting.theme || '#2C51D9',
      sideTheme: storageSetting.sideTheme || sideTheme,
      showSettings: showSettings,
      topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
      tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
      fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
      sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
      dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle,
      isDark: isDark.value
    }),
    actions: {
      // ä¿®æ”¹å¸ƒå±€è®¾ç½®
      changeSetting(data) {
        const { key, value } = data
        if (this.hasOwnProperty(key)) {
          this[key] = value
        }
      },
      // è®¾ç½®ç½‘页标题
      setTitle(title) {
        this.title = title
        useDynamicTitle()
      },
      // åˆ‡æ¢æš—黑模式
      toggleTheme() {
        this.isDark = !this.isDark
        toggleDark()
const useSettingsStore = defineStore("settings", {
  state: () => ({
    title: "",
    theme: storageSetting.theme || "#002fa7",
    sideTheme: storageSetting.sideTheme || sideTheme,
    showSettings: showSettings,
    topNav:
      storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
    tagsView:
      storageSetting.tagsView === undefined
        ? tagsView
        : storageSetting.tagsView,
    fixedHeader:
      storageSetting.fixedHeader === undefined
        ? fixedHeader
        : storageSetting.fixedHeader,
    sidebarLogo:
      storageSetting.sidebarLogo === undefined
        ? sidebarLogo
        : storageSetting.sidebarLogo,
    dynamicTitle:
      storageSetting.dynamicTitle === undefined
        ? dynamicTitle
        : storageSetting.dynamicTitle,
    isDark: isDark.value,
  }),
  actions: {
    // ä¿®æ”¹å¸ƒå±€è®¾ç½®
    changeSetting(data) {
      const { key, value } = data;
      if (this.hasOwnProperty(key)) {
        this[key] = value;
      }
    }
  })
    },
    // è®¾ç½®ç½‘页标题
    setTitle(title) {
      this.title = title;
      useDynamicTitle();
    },
    // åˆ‡æ¢æš—黑模式
    toggleTheme() {
      this.isDark = !this.isDark;
      toggleDark();
    },
  },
});
export default useSettingsStore
export default useSettingsStore;
src/views/equipmentManagement/ledger/Modal.vue
@@ -31,7 +31,7 @@
  modalOptions,
  handleConfirm,
  closeModal,
} = useModal();
} = useModal({ title: "设备台账" });
const sendForm = async () => {
  loading.value = true;
src/views/equipmentManagement/repair/Form/MaintainForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
<template>
  <el-form :model="form" label-width="80px">
    <el-form-item label="维修人">
      <el-input v-model="form.maintenanceName" placeholder="请输入维修人" />
    </el-form-item>
    <el-form-item label="维修结果">
      <el-input v-model="form.maintenanceResult" placeholder="请输入维修结果" />
    </el-form-item>
    <el-form-item label="维修结果">
      <el-date-picker
        v-model="form.maintenanceTime"
        placeholder="请选择维修日期"
        format="YYYY-MM-DD"
        value-format="YYYY-MM-DD"
        type="date"
        clearable
        style="width: 100%"
      />
    </el-form-item>
  </el-form>
</template>
<script setup>
import useFormData from "@/hooks/useFormData";
defineOptions({
  name: "设备维修表单",
});
const { form, resetForm } = useFormData({
  maintenanceName: undefined, // ç»´ä¿®åç§°
  maintenanceResult: undefined, // ç»´ä¿®ç»“æžœ
  maintenanceTime: undefined, // ç»´ä¿®æ—¥æœŸ
});
const setForm = (data) => {
  form.maintenanceName = data.maintenanceName;
  form.maintenanceResult = data.maintenanceResult;
  form.maintenanceTime = data.maintenanceTime;
};
const getForm = () => {
  return form;
};
defineExpose({
  getForm,
  setForm,
  resetForm,
});
</script>
<style lang="scss" scoped></style>
src/views/equipmentManagement/repair/Form/RepairForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
<template>
  <el-form :model="form" label-width="100px">
    <el-row>
      <el-col :span="12">
        <el-form-item label="设备名称">
          <el-select v-model="form.deviceLedgerId" @change="setDeviceModel">
            <el-option
              v-for="(item, index) in deviceOptions"
              :key="index"
              :label="item.deviceName"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="规格型号">
          <el-input
            v-model="form.deviceModel"
            placeholder="请输入规格型号"
            disabled
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="报修日期">
          <el-date-picker
            v-model="form.repairTime"
            placeholder="请选择报修日期"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            type="date"
            clearable
            style="width: 100%"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="报修人">
          <el-input v-model="form.repairName" placeholder="请输入报修人" />
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="故障现象">
          <el-input
            v-model="form.remark"
            :rows="2"
            type="textarea"
            placeholder="请输入故障现象"
          />
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>
<script setup>
import useFormData from "@/hooks/useFormData";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import { onMounted } from "vue";
defineOptions({
  name: "设备报修表单",
});
const deviceOptions = ref([]);
const loadDeviceName = async () => {
  const { data } = await getDeviceLedger();
  deviceOptions.value = data;
};
const { form, resetForm } = useFormData({
  deviceLedgerId: undefined, // è®¾å¤‡Id
  deviceName: undefined, // è®¾å¤‡åç§°
  deviceModel: undefined, // è§„格型号
  repairTime: undefined, // æŠ¥ä¿®æ—¥æœŸ
  repairName: undefined, // æŠ¥ä¿®äºº
  remark: undefined, // æ•…障现象
});
const setDeviceModel = (id) => {
  const option = deviceOptions.value.find((item) => item.id === id);
  form.deviceModel = option.deviceModel;
};
const getForm = () => {
  return form;
};
const setForm = (data) => {
  form.deviceLedgerId = data.deviceLedgerId;
  form.deviceName = data.deviceName;
  form.deviceModel = data.deviceModel;
  form.repairTime = data.repairTime;
  form.repairName = data.repairName;
  form.remark = data.remark;
};
onMounted(() => {
  loadDeviceName();
});
defineExpose({
  loadDeviceName,
  resetForm,
  getForm,
  setForm,
});
</script>
<style lang="scss" scoped></style>
src/views/equipmentManagement/repair/Modal/MaintainModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
<template>
  <el-drawer v-model="visible" :title="modalOptions.title" direction="ltr">
    <MaintainForm ref="maintainFormRef" />
    <template #footer>
      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
      <el-button type="primary" @click="sendForm" :loading="loading">
        {{ modalOptions.confirmText }}
      </el-button>
    </template>
  </el-drawer>
</template>
<script setup>
import { useModal } from "@/hooks/useModal";
import MaintainForm from "../Form/MaintainForm.vue";
import { addMaintain } from "@/api/equipmentManagement/repair";
defineOptions({
  name: "维修模态框",
});
const maintainFormRef = ref();
const emits = defineEmits(["ok"]);
const {
  id,
  visible,
  loading,
  openModal,
  modalOptions,
  handleConfirm,
  closeModal,
} = useModal({ title: "设备维修" });
const sendForm = async () => {
  loading.value = true;
  const form = await maintainFormRef.value.getForm();
  const { code } = await addMaintain({ id: id.value, ...form });
  if (code == 200) {
    emits("ok");
    maintainFormRef.value.resetForm();
    closeModal();
  }
  loading.value = false;
};
const open = async (id, row) => {
  openModal(id);
  await nextTick();
  maintainFormRef.value.setForm(row);
};
defineExpose({
  open,
});
</script>
<style lang="scss" scoped></style>
src/views/equipmentManagement/repair/Modal/RepairModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
<template>
  <el-dialog v-model="visible" :title="modalOptions.title" @close="close">
    <RepairForm ref="repairFormRef" />
    <template #footer>
      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
      <el-button type="primary" @click="sendForm" :loading="loading">
        {{ modalOptions.confirmText }}
      </el-button>
    </template>
  </el-dialog>
</template>
<script setup>
import { useModal } from "@/hooks/useModal";
import RepairForm from "../Form/RepairForm.vue";
import {
  addRepair,
  editRepair,
  getRepairById,
} from "@/api/equipmentManagement/repair";
import { ElMessage } from "element-plus";
defineOptions({
  name: "设备报修弹窗",
});
const emits = defineEmits(["ok"]);
const repairFormRef = ref();
const {
  id,
  visible,
  loading,
  openModal,
  modalOptions,
  handleConfirm,
  closeModal,
} = useModal({ title: "设备报修" });
const sendForm = async () => {
  loading.value = true;
  const form = await repairFormRef.value.getForm();
  const { code } = id.value
    ? await editRepair({ id: unref(id), ...form })
    : await addRepair(form);
  if (code == 200) {
    ElMessage.success(`${id ? "编辑" : "新增"}报修成功`);
    closeModal();
    emits("ok");
  }
  loading.value = false;
};
const openEdit = async (id) => {
  const { data } = await getRepairById(id);
  openModal(id);
  await nextTick();
  await repairFormRef.value.setForm(data);
};
const close = () => {
  repairFormRef.value.resetForm();
  closeModal();
};
defineExpose({
  openModal,
  openEdit,
});
</script>
src/views/equipmentManagement/repair/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,207 @@
<template>
  <div class="app-container">
    <div class="table_list">
      <div class="actions">
        <el-text class="mx-1" size="large">设备报修</el-text>
        <div>
          <el-button
            type="primary"
            icon="Plus"
            :disabled="multipleList.length !== 1"
            @click="addMaintain"
          >
            æ–°å¢žç»´ä¿®
          </el-button>
          <el-button type="success" icon="Van" @click="addRepair">
            æ–°å¢žæŠ¥ä¿®
          </el-button>
          <el-button
            type="danger"
            icon="Delete"
            :disabled="multipleList.length <= 0"
            @click="delRepairByIds(multipleList.map((item) => item.id))"
          >
            æ‰¹é‡åˆ é™¤
          </el-button>
        </div>
      </div>
      <PIMTable
        rowKey="id"
        isSelection
        :column="columns"
        :tableData="dataList"
        :page="{
          current: pagination.currentPage,
          size: pagination.pageSize,
          total: pagination.total,
        }"
        @selection-change="handleSelectionChange"
      >
        <template #statusRef="{ row }">
          <el-tag v-if="row.status === 1" type="success">完结</el-tag>
          <el-tag v-if="row.status === 0" type="error">待维修</el-tag>
        </template>
        <template #operation="{ row }">
          <el-button
            type="primary"
            text
            icon="editPen"
            @click="editRepair(row.id)"
          >
            ç¼–辑
          </el-button>
          <el-button
            type="danger"
            text
            icon="delete"
            @click="delRepairByIds(row.id)"
          >
            åˆ é™¤
          </el-button>
        </template>
      </PIMTable>
    </div>
    <RepairModal ref="repairModalRef" @ok="getTableData" />
    <MaintainModal ref="maintainModalRef" @ok="getTableData" />
  </div>
</template>
<script setup>
import { usePaginationApi } from "@/hooks/usePaginationApi";
import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair";
import { onMounted } from "vue";
import RepairModal from "./Modal/RepairModal.vue";
import { ElMessageBox, ElMessage } from "element-plus";
import dayjs from "dayjs";
import MaintainModal from "./Modal/MaintainModal.vue";
defineOptions({
  name: "设备报修",
});
// æ¨¡æ€æ¡†å®žä¾‹
const repairModalRef = ref();
const maintainModalRef = ref();
// è¡¨æ ¼å¤šé€‰æ¡†é€‰ä¸­é¡¹
const multipleList = ref([]);
// è¡¨æ ¼é’©å­
const { filters, columns, dataList, pagination, getTableData, resetFilters } =
  usePaginationApi(
    getRepairPage,
    {
      searchText: undefined,
    },
    [
      {
        label: "设备名称",
        align: "center",
        prop: "deviceName",
      },
      {
        label: "规格型号",
        align: "center",
        prop: "deviceModel",
      },
      {
        label: "报修日期",
        align: "center",
        prop: "repairTime",
        formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"),
      },
      {
        label: "报修人",
        align: "center",
        prop: "repairName",
      },
      {
        label: "故障现象",
        align: "center",
        prop: "remark",
      },
      {
        label: "维修人",
        align: "center",
        prop: "maintenanceName",
      },
      {
        label: "维修结果",
        align: "center",
        prop: "maintenanceResult",
      },
      {
        label: "维修日期",
        align: "center",
        prop: "maintenanceTime",
        formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
      },
      {
        label: "状态",
        align: "center",
        prop: "status",
        dataType: "slot",
        slot: "statusRef",
      },
      {
        fixed: "right",
        label: "操作",
        dataType: "slot",
        slot: "operation",
        align: "center",
        width: "200px",
      },
    ]
  );
// å¤šé€‰åŽåšä»€ä¹ˆ
const handleSelectionChange = (selectionList) => {
  multipleList.value = selectionList;
};
// æ–°å¢žæŠ¥ä¿®
const addRepair = () => {
  repairModalRef.value.openModal();
};
// ç¼–辑报修
const editRepair = (id) => {
  repairModalRef.value.openEdit(id);
};
// æ–°å¢žç»´ä¿®
const addMaintain = () => {
  const row = multipleList.value[0];
  maintainModalRef.value.open(row.id, row);
};
// å•行删除
const delRepairByIds = async (ids) => {
  ElMessageBox.confirm("确认删除报修数据, æ­¤æ“ä½œä¸å¯é€†?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const { code } = await delRepair(ids);
    if (code === 200) {
      ElMessage.success("删除成功");
      getTableData();
    }
  });
};
onMounted(() => {
  getTableData();
});
</script>
<style lang="scss" scoped>
.table_list {
  margin-top: unset;
}
.actions {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
}
</style>
src/views/procurementManagement/invoiceEntry/components/ExpandTable.vue
@@ -55,28 +55,28 @@
      label: "含税单价(元)",
      prop: "taxInclusiveUnitPrice",
      formatData: (val) => {
        return parseFloat(val).toFixed(2) ?? 0;
        return val ? parseFloat(val).toFixed(2) : "-";
      },
    },
    {
      label: "含税总价(元)",
      prop: "taxInclusiveTotalPrice",
      formatData: (val) => {
        return parseFloat(val).toFixed(2) ?? 0;
        return val ? parseFloat(val).toFixed(2) : "-";
      },
    },
    {
      label: "不含税总价(元)",
      prop: "taxExclusiveTotalPrice",
      formatData: (val) => {
        return parseFloat(val).toFixed(2) ?? 0;
        return val ? parseFloat(val).toFixed(2) : "-";
      },
    },
    {
      label: "本次来票金额(元)",
      prop: "ticketsAmount",
      formatData: (val) => {
        return parseFloat(val).toFixed(2) ?? 0;
        return val ? parseFloat(val).toFixed(2) : "-";
      },
    },
    {
@@ -87,7 +87,7 @@
      label: "未来票金额(元)",
      prop: "futureTicketsAmount",
      formatData: (val) => {
        return parseFloat(val).toFixed(2) ?? 0;
        return val ? parseFloat(val).toFixed(2) : "-";
      },
    },
  ],
src/views/procurementManagement/invoiceEntry/components/Modal.vue
@@ -235,7 +235,7 @@
    prop: "taxInclusiveUnitPrice",
    width: 150,
    formatData: (val) => {
      return parseFloat(val).toFixed(2) ?? 0;
      return val ? parseFloat(val).toFixed(2) : 0;
    },
  },
  {
@@ -385,7 +385,8 @@
        salesContractNo: form.salesContractNo,
        projectName: form.projectName,
        productData: form.productData,
        issUerId: form.issUerId, // å½•入人
        issueDate: form.entryDate,
        issUerId: form.issUerId, // å½•入人id
        issUer: form.issUer, // å½•入人
        salesContractNoId: form.salesContractNoId,
        supplierName: form.supplierName,
src/views/procurementManagement/invoiceEntry/index.vue
@@ -114,21 +114,21 @@
      label: "合同金额(元)",
      prop: "contractAmount",
      formatData: (val) => {
        return parseFloat(val).toFixed(2) ?? 0;
        return val ? parseFloat(val).toFixed(2) : 0;
      },
    },
    {
      label: "已开票金额(元)",
      prop: "receiptPaymentAmount",
      formatData: (val) => {
        return parseFloat(val).toFixed(2) ?? 0;
        return val ? parseFloat(val).toFixed(2) : 0;
      },
    },
    {
      label: "待开票金额(元)",
      prop: "unReceiptPaymentAmount",
      formatData: (val) => {
        return parseFloat(val).toFixed(2) ?? 0;
        return val ? parseFloat(val).toFixed(2) : 0;
      },
    },
    // {
src/views/procurementManagement/paymentEntry/index.vue
@@ -254,21 +254,21 @@
    label: "发票金额(元)",
    prop: "invoiceAmount",
    formatData: (params) => {
      return parseFloat(params).toFixed(2);
      return params ? parseFloat(params).toFixed(2) : 0;
    },
  },
  {
    label: "已付款金额(元)",
    prop: "paymentAmountTotal",
    formatData: (params) => {
      return parseFloat(params).toFixed(2);
      return params ? parseFloat(params).toFixed(2) : 0;
    },
  },
  {
    label: "待付款金额(元)",
    prop: "unPaymentAmountTotal",
    formatData: (params) => {
      return parseFloat(params).toFixed(2);
      return params ? parseFloat(params).toFixed(2) : 0;
    },
  },
]);
src/views/procurementManagement/paymentHistory/index.vue
@@ -74,7 +74,7 @@
    label: "付款金额",
    prop: "currentPaymentAmount",
    formatData: (params) => {
      return parseFloat(params).toFixed(2);
      return params ? parseFloat(params).toFixed(2) : 0;
    },
  },
  {
src/views/procurementManagement/paymentLedger/index.vue
@@ -168,14 +168,14 @@
    label: "发票金额(元)",
    prop: "invoiceAmount",
    formatData: (params) => {
      return parseFloat(params).toFixed(2);
      return params ? parseFloat(params).toFixed(2) : 0;
    },
  },
  {
    label: "付款金额(元)",
    prop: "currentPaymentAmount",
    formatData: (params) => {
      return parseFloat(params).toFixed(2);
      return params ? parseFloat(params).toFixed(2) : 0;
    },
  },
  {
src/views/procurementManagement/procurementInvoiceLedger/index.vue
@@ -136,7 +136,7 @@
      prop: "taxInclusiveTotalPrice",
      align: "center",
      formatData: (cell) => {
        return parseFloat(cell).toFixed(2);
        return cell ? parseFloat(cell).toFixed(2) : 0;
      },
    },
    {
@@ -149,7 +149,7 @@
      prop: "ticketsAmount",
      align: "center",
      formatData: (cell) => {
        return parseFloat(cell).toFixed(2);
        return cell ? parseFloat(cell).toFixed(2) : 0;
      },
    },
    {
@@ -157,7 +157,7 @@
      prop: "unTicketsPrice",
      align: "center",
      formatData: (cell) => {
        return parseFloat(cell).toFixed(2);
        return cell ? parseFloat(cell).toFixed(2) : 0;
      },
    },
    {
src/views/salesManagement/invoiceRegistration/index.vue
@@ -424,6 +424,7 @@
    productData: [],
    invoiceNo: "",
    createUer: "",
    issueDate: "",
  },
  rules: {
    salesLedgerId: [{ required: true, message: "请选择", trigger: "change" }],
src/views/salesManagement/receiptPaymentHistory/index.vue
@@ -97,7 +97,7 @@
    label: "回款金额(元)",
    prop: "receiptPaymentAmount",
    formatData: (params) => {
      return parseFloat(params).toFixed(2);
      return params ? parseFloat(params).toFixed(2) : 0;
    },
  },
  {