From 02dab18683eab22bf7a37c404a17d9174820f29c Mon Sep 17 00:00:00 2001
From: buhuazhen <hua100783@gmail.com>
Date: 星期三, 27 八月 2025 14:22:59 +0800
Subject: [PATCH] :fire: 优化 采购页面添加类型 新增应付页面

---
 src/views/procureMent/index.vue                       |   60 ++++
 src/api/payable/index.js                              |   18 +
 src/store/modules/dict.js                             |   34 ++
 src/api/system/dict/data.js                           |    8 
 src/views/payable/index.vue                           |  399 ++++++++++++++++++++++++++++
 src/views/procureMent/components/ProductionDialog.vue |   29 ++
 src/App.vue                                           |    2 
 src/views/payable/components/PayableDialog.vue        |  279 +++++++++++++++++++
 8 files changed, 822 insertions(+), 7 deletions(-)

diff --git a/src/App.vue b/src/App.vue
index 31839f2..85503ea 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -4,9 +4,11 @@
 
 <script setup>
 import useSettingsStore from '@/store/modules/settings'
+import dictStore from '@/store/modules/dict'
 import { handleThemeStyle } from '@/utils/theme'
 
 onMounted(() => {
+  dictStore().initDict()
   nextTick(() => {
     // 鍒濆鍖栦富棰樻牱寮�
     handleThemeStyle(useSettingsStore().theme)
diff --git a/src/api/payable/index.js b/src/api/payable/index.js
new file mode 100644
index 0000000..1ab9d15
--- /dev/null
+++ b/src/api/payable/index.js
@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+// 娣诲姞
+export function addDuePayable(query) {
+    return request({
+        url: '/duePayable/addDuePayable',
+        method: 'post',
+        data: query
+    })
+}
+// 鍒嗛〉鏌ヨ
+export function findPayablePage(query) {
+    return request({
+        url: '/duePayable/list',
+        method: 'get',
+        params: query
+    })
+}
diff --git a/src/api/system/dict/data.js b/src/api/system/dict/data.js
index 6c9eb79..8d2aefa 100644
--- a/src/api/system/dict/data.js
+++ b/src/api/system/dict/data.js
@@ -1,5 +1,13 @@
 import request from '@/utils/request'
 
+export function ListAllData(){
+  return request({
+    url: '/system/dict/data/dictDataList',
+    method: 'get'
+  })
+}
+
+
 // 鏌ヨ瀛楀吀鏁版嵁鍒楄〃
 export function listData(query) {
   return request({
diff --git a/src/store/modules/dict.js b/src/store/modules/dict.js
index e58e4ec..7521a74 100644
--- a/src/store/modules/dict.js
+++ b/src/store/modules/dict.js
@@ -1,15 +1,43 @@
+import {ListAllData} from "@/api/system/dict/data"
+
 const useDictStore = defineStore(
   'dict',
   {
     state: () => ({
-      dict: new Array()
+      dict: []
     }),
     actions: {
+      async initDict() {
+        const response = await ListAllData()
+        this.dict = response.data
+      },
+
+      // 鏍规嵁瀛楀吀绫诲瀷鑾峰彇瀛楀吀
+      getDictTypeList(_type) {
+        if (_type == null || _type === "") {
+          return null;
+        }
+        return this.dict.filter(item => item.type === _type);
+      },
+
+      getDictDataByTypeAndValue(_type,_value){
+        if (_type == null || _value == null) {
+          return {
+            type:"",
+            value:"",
+            label:""
+          };
+        }
+        return this.dict.find(item => item.type == _type && item.value == _value ) || null;
+
+      },
+
       // 鑾峰彇瀛楀吀
       getDict(_key) {
         if (_key == null && _key == "") {
           return null
         }
+        // console.log(this.dict)
         try {
           for (let i = 0; i < this.dict.length; i++) {
             if (this.dict[i].key == _key) {
@@ -48,9 +76,7 @@
       cleanDict() {
         this.dict = new Array()
       },
-      // 鍒濆瀛楀吀
-      initDict() {
-      }
+
     }
   })
 
diff --git a/src/views/payable/components/PayableDialog.vue b/src/views/payable/components/PayableDialog.vue
new file mode 100644
index 0000000..f78af79
--- /dev/null
+++ b/src/views/payable/components/PayableDialog.vue
@@ -0,0 +1,279 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogPayableFormVisible"
+        :title="title"
+        width="600"
+        :close-on-click-modal="false"
+        @close="handleClose"
+    >
+      <el-form
+          ref="formRef"
+          :model="form"
+          :rules="rules"
+          label-width="auto"
+          class="production-form"
+          label-position="right"
+          style="max-width: 400px; margin: 0 auto"
+      >
+        <el-form-item label="鍙戠エ鍙�" prop="ticketNo">
+          <el-input
+              v-model.number="form.ticketNo"
+              placeholder="璇疯緭鍏ュ彂绁ㄥ彿"
+              :disabled="isViewMode"
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item label="浠樻閲戦" prop="paymentAmount">
+          <el-input
+              v-model.number="form.paymentAmount"
+              placeholder="璇疯緭鍏ヤ粯娆鹃噾棰�"
+              :disabled="isViewMode"
+          >
+             <template v-slot:suffix>
+              <i style="font-style: normal">鍏�</i>
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item label="浠樻绫诲瀷" prop="payableType">
+          <el-select
+              v-model="form.payableType"
+              placeholder="璇烽�夋嫨绫诲瀷"
+              :disabled="isViewMode"
+          >
+            <el-option
+                v-for="item in payableTypeList"
+                :key="item.value"
+                :label="item.label"
+                :value="Number(item.value)"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="涓婁紶闄勪欢" prop="attachUpload">
+          <el-upload
+              class="upload-demo"
+              drag
+              :fileList="form.fileList"
+              :action="uploadFileUrl"
+              :headers="headers"
+              :http-request="UploadImage"
+              :on-success="handleUploadSuccess"
+              :on-remove="handleUploadRemove"
+              :on-preview="handleUploadPreview"
+              multiple>
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="鐧昏浜�" prop="registrantId">
+          <el-input
+              :value="match(form.registrantId)"
+              v-model.number="form.registrantId"
+              disabled
+              placeholder="璇疯緭鍏�"
+          />
+        </el-form-item>
+        <el-form-item label="鐧昏鏃ユ湡" prop="registrationDate">
+          <el-date-picker
+              disabled
+              v-model="form.registrationDate"
+              type="date"
+              placeholder="YYYY-MM-DD"
+              style="width: 100%"
+              value-format="YYYY-MM-DD"
+          />
+        </el-form-item>
+
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <!-- 閲嶇疆鍜屽彇娑� -->
+          <el-button
+              @click="handleClose"
+              v-if="title.includes('鏂板') || title.includes('鏌ョ湅')"
+          >鍙栨秷
+          </el-button>
+          <el-button @click="handleReset" v-if="title.includes('缂栬緫')"
+          >閲嶇疆
+          </el-button>
+          <el-button type="primary" v-if="!isViewMode" @click="handleSubmit"
+          >纭</el-button
+          >
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="ProductionDialog">
+import {ref, defineProps, watch, onMounted, nextTick, computed,reactive,defineEmits} from "vue";
+import axios from "axios";
+import {addDuePayable} from "@/api/payable/index.js"
+import {ElMessage} from "element-plus";
+
+import useUserStore from "@/store/modules/user.js";
+import useDictStore from "@/store/modules/dict.js"
+import {getToken} from "@/utils/auth.js";
+const uploadFileUrl = computed(() => import.meta.env.VITE_APP_BASE_API + "/common/minioUploads");
+const headers = computed(() => ({ Authorization: "Bearer " + getToken() }));
+
+
+
+const props = defineProps({
+  title: {
+    type: String,
+    default: "",
+  },
+  statusType: { type: Number, default: 0 },
+  dialogPayableFormVisible: {
+    type: Boolean,
+    required: true
+  },
+});
+
+const handleUploadRemove = (it)=>{
+  form.value.fileList = form.value.fileList.filter(f => f.uid !== it.uid);
+
+}
+const handleUploadPreview = (it)=>{
+  const link = document.createElement("a");
+  if(it.url){
+    link.href = it.url
+  }else {
+    link.href = form.value.fileList.value.find(fl=>fl.uid === it.uid).url;
+  }
+  link.download = it.name;
+  link.click();
+}
+
+const handleUploadSuccess = (res,file)=>{
+  form.value.fileList.push(...res.data.map((it,index)=>{
+    return {
+      id:it.id,
+      url:it.downloadUrl,
+      name:it.originalFilename,
+      status:"success",
+      uid:file.uid
+    }
+  }))
+}
+
+// 鏂囦欢涓婁紶澶勭悊
+const UploadImage = (param) => {
+  const formData = new FormData();
+  formData.append("files", param.file);
+  formData.append("type", props.statusType);
+  axios.post(uploadFileUrl.value, formData, {
+    headers: {
+      "Content-Type": "multipart/form-data",
+      ...headers.value,
+    },
+    onUploadProgress: (progressEvent) => {
+      const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
+      param.onProgress({ percent });
+    },
+  })
+      .then((response) => {
+        if (response.data.code === 200) {
+          handleUploadSuccess(response.data, param.file);
+          ElMessage.success("涓婁紶鎴愬姛");
+        } else {
+          param.onError(new Error(response.data.msg));
+          ElMessage.error(response.data.msg);
+        }
+      })
+      .catch((error) => {
+        param.onError(error);
+      });
+};
+const emit = defineEmits(["update:dialogPayableFormVisible", "success"]);
+const dialogPayableFormVisible = defineModel("dialogPayableFormVisible", {
+  required: true,
+  type: Boolean,
+});
+const form = defineModel("form", {
+  required: true,
+  type: Object,
+});
+
+
+const payableTypeList = ref([])
+const isViewMode = computed(() => props.title.includes("鏌ョ湅"));
+
+const userStore = useUserStore();
+const userInfo = ref({});
+const match = () => {
+  return userInfo.value.nickName || "鏈煡鐢ㄦ埛";
+};
+
+
+
+
+//###
+
+onMounted(async () => {
+
+  payableTypeList.value = useDictStore().getDictTypeList("payable_type").map((item) => ({
+    value: item.value,
+    label: item.label,
+  }))
+
+  let res = await userStore.getInfo();
+  userInfo.value = res.user;
+
+});
+const rules = {
+
+  payableType: [
+    {required: true, message: "璇烽�夋嫨绫诲瀷", trigger: "change"}
+  ],
+  paymentAmount: [
+    {required: true, message: "璇疯緭鍏ラ噾棰�", trigger: "blur"}
+  ],
+  ticketNo: [
+    {required: true, message: "璇疯緭鍏ュ彂绁ㄥ彿", trigger: "blur"}
+  ]
+
+};
+// 鍏抽棴寮圭獥
+const handleClose = () => {
+  dialogPayableFormVisible.value = false;
+  form.value.fileList.value = []
+};
+
+const handleReset = async ()=>{
+
+}
+
+const formRef = ref(null);
+// 鎻愪氦琛ㄥ崟
+const handleSubmit = async () => {
+  // 鏂囦欢澶勭悊鍙幏鍙杋d 杩涜鎷兼帴
+  if (!formRef.value) return;
+  formRef.value.validate((valid) => {
+    if (valid) {
+      const obj = ref({});
+      form.value.attachUpload = ""
+      if (form.value.fileList.length > 0){
+        form.value.attachUpload = form.value.fileList.map(it => it.id).join(",")
+      }
+
+      let result = addDuePayable({
+        ...form.value
+      })
+
+      obj.value = {
+        ...form.value,
+        result
+      }
+      emit("success", obj.value);
+    }
+  })
+};
+
+</script>
+
+<style lang="scss" scoped>
+
+
+</style>
diff --git a/src/views/payable/index.vue b/src/views/payable/index.vue
new file mode 100644
index 0000000..4bd682c
--- /dev/null
+++ b/src/views/payable/index.vue
@@ -0,0 +1,399 @@
+<template>
+  <div class="app-container">
+    <el-form :inline="true" :model="queryParams" class="search-form">
+      <el-form-item v-if="shouldShowSearch" label="鎼滅储">
+        <el-input
+            v-model="queryParams.searchAll"
+            :placeholder="searchPlaceholder"
+            clearable
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="handleQuery">鏌ヨ</el-button>
+        <!--        <el-button @click="resetQuery">閲嶇疆</el-button>-->
+      </el-form-item>
+    </el-form>
+    <el-card>
+
+
+      <!-- 鎿嶄綔鎸夐挳鍖� -->
+      <!--      <el-row :gutter="24" class="table-toolbar">-->
+      <!--        <el-button-->
+      <!--            :icon="Plus"-->
+      <!--            type="primary"-->
+      <!--            v-show="activeTab === 'payable'"-->
+      <!--            @click="handleAdd"-->
+      <!--        >鏂板搴斾粯娆鹃」</el-button>-->
+
+      <!--      </el-row>-->
+      <!-- 琛ㄦ牸缁勪欢 -->
+      <div class="table-container">
+        <!-- 鍔犺浇鐘舵�� -->
+        <el-skeleton v-if="loading" animated>
+          <template #template>
+            <el-skeleton-item variant="h1" style="width: 40%"/>
+            <div style="padding: 14px;">
+              <el-skeleton-item variant="text"/>
+              <el-skeleton-item variant="text"/>
+              <el-skeleton-item variant="text"/>
+            </div>
+          </template>
+        </el-skeleton>
+
+        <!-- 鏁版嵁琛ㄦ牸 -->
+        <data-table
+            v-else
+            :showOverflowTooltip="false"
+            :border="true"
+            @edit="handleEdit"
+            :columns="columns"
+            :loading="loading"
+            style="width: 100%; height: calc(100vh - 29em)"
+            :show-selection="activeTab === 'payable'"
+            :table-data="tableData"
+        >
+          <!-- 绌虹姸鎬佹彃妲� -->
+          <template #empty>
+            <el-empty
+                :description="`鏆傛棤${currentTabConfig?.label || ''}鏁版嵁`"
+                :image-size="120"
+            >
+              <template #description>
+                <p>鏆傛棤{{ currentTabConfig?.label || '' }}鏁版嵁</p>
+              </template>
+            </el-empty>
+          </template>
+        </data-table>
+      </div>
+
+
+      <pagination
+          v-if="total > 0"
+          :layout="'total, prev, pager, next, jumper'"
+          :limit="state.pageSize"
+          :current-page="state.current"
+          :total="total"
+          @pagination="handlePageChange"
+      />
+
+      <!-- 鏌ョ湅璇︽儏寮圭獥 -->
+      <DilogTable
+          v-model="dialogTableVisible"
+          :title="dialogTableTitle"
+          :table-data="dialogTableData"
+          :columns="dialogTableColumns"
+          @submit="handleSubmit"
+          @success="payableHandleSuccess"
+          width="70%"
+          height="500px"
+      />
+    </el-card>
+    <PayableDialog
+        v-model:dialogPayableFormVisible="dialogPayableFormVisible"
+        v-model:form="copyForm"
+        :title="title"
+        @submit="handleSubmit"
+        @success="payableHandleSuccess"
+        ref="productionDialogs">
+    </PayableDialog>>
+  </div>
+</template>
+
+<script setup>
+import {computed, onMounted, reactive, ref, nextTick, toRefs} from "vue";
+import {ElMessage} from "element-plus";
+import {Delete, Plus} from "@element-plus/icons-vue";
+
+// 缁勪欢瀵煎叆
+import DataTable from "@/components/Table/ETable.vue";
+import Pagination from "@/components/PIMTable/Pagination.vue";
+import DilogTable from "@/components/dialog/DilogTable.vue";
+
+// API 鏈嶅姟瀵煎叆
+import {findPayablePage} from "@/api/payable/index"
+
+const userStore = useUserStore();
+const dictStore = useDictStore()
+import useUserStore from "@/store/modules/user";
+import useDictStore from "@/store/modules/dict"
+import PayableDialog from "@/views/payable/components/PayableDialog.vue";
+
+let userList = ref([]);
+userStore.getUserList().then((res) => {
+  userList.value = res;
+});
+
+
+// 鍝嶅簲寮忕姸鎬佺鐞� - 浣跨敤瑙f瀯鍜岄粯璁ゅ��
+const productionDialogs = ref(null); // 娣诲姞ref澹版槑
+const initFormState = () => ({consumables: false});
+const dialogPayableFormVisible = ref(false);
+const addOrEdit = ref("edit");
+const state = reactive({
+  form: initFormState(),
+  title: "",
+  copyForm: {},
+  loading: false,
+  activeTab: "payable",
+  selectedRows: [],
+  tableData: [],
+  // 鍒嗛〉鐘舵��
+  pageNum: 1,
+  pageSize: 10,
+  current: 1,
+  total: 0,
+  // 鏌ヨ鍙傛暟
+  queryParams: {
+    searchAll: "",
+  },
+});
+const userInfo = ref({});
+
+onMounted(() => {
+  let res = userStore.getInfo();
+  userInfo.value = res.user;
+  getList()
+})
+const handleEdit = (row) => {
+  form.value = JSON.parse(JSON.stringify(row));
+  addOrEdit.value = "edit";
+  handleAddEdit()
+}
+const handleAddEdit = () => {
+  addOrEdit.value == "add" ? (title.value = "鏂板") : addOrEdit.value == "viewRow" ? (title.value = "鏌ョ湅") : (title.value = "缂栬緫");
+  title.value = title.value + "搴斾粯绠$悊";
+  openDialog();
+};
+
+const openDialog = () => {
+  if (addOrEdit.value === "edit" || addOrEdit.value === "viewRow") {
+    // 纭繚澶嶅埗涓�浠芥暟鎹紝閬垮厤鐩存帴寮曠敤
+    copyForm.value = JSON.parse(JSON.stringify(form.value));
+    // console.log(copyForm.value)
+    copyForm.value.fileList = copyForm.value.attachFileList.map((item) => {
+      return {
+        id: item.id,
+        url: item.downloadUrl,
+        uid: item.id,
+        status: "success",
+        name: item.originalFilename
+      }
+    })
+    dialogPayableFormVisible.value = true;
+    // 瑙﹀彂ref閲岄潰鐨勬柟娉�
+    return;
+  }
+};
+
+
+const handleQuery = () => {
+  state.loading = true;
+  state.current = 1;
+  getList()
+}
+
+const handlePageChange = (it) => {
+  state.current = it.page
+  getList();
+}
+
+
+
+
+const getList = async () => {
+  loading.value = true;
+  try {
+    let resp = await findPayablePage(
+        {
+          current: state.current,
+          pageSize: state.current
+          , ...state.queryParams
+        })
+    tableData.value = resp.data.records
+    total.value = resp.data.total || 0;
+  } finally {
+    loading.value = false;
+  }
+}
+
+// 浣跨敤瑙f瀯绠�鍖栬闂�
+const {
+  form,
+  title,
+  copyForm,
+  loading,
+  activeTab,
+  selectedRows,
+  current,
+  tableData,
+  pageNum,
+  pageSize,
+  total,
+  queryParams,
+} = toRefs(state);
+
+// 娣诲姞缂哄け鐨勫搷搴斿紡鍙橀噺
+const dialogTableVisible = ref(false);
+const dialogTableTitle = ref('');
+const dialogTableData = ref([]);
+const dialogTableColumns = ref([]);
+
+
+const payableHandleSuccess = (val) => {
+  ElMessage.success("鎿嶄綔鎴愬姛");
+  dialogPayableFormVisible.value = false;
+  getList()
+}
+const handleSubmit = (val) => {
+  if (val.result.code !== 200) {
+    ElMessage.error("鎿嶄綔澶辫触锛�" + val.result.msg);
+    return;
+  }
+  ElMessage.success(val.title + val.result.msg);
+  dialogPayableFormVisible.value = false;
+  getList();
+};
+
+// 鏍囩椤甸厤缃� - 渚夸簬鍚庣画鎵╁睍
+const tabsConfig = {
+  payable: {
+    searchPlaceholder: "",
+    showSearch: true,
+    // deleteApi: ,
+    columns: [
+      /* 鏆傛椂涓嶇煡閬撴槸鍚﹂渶瑕�      {prop: "equipmentNo", label: "渚涘簲鍟嗗悕绉�", minWidth: 100},*/
+      {prop: "ticketNo", label: "鍙戠エ鍙�", minWidth: 100},
+      {prop: "paymentAmount", label: "浠樻閲戦(鍏�)", minWidth: 100},
+      // {prop: "specification", label: "闄勪欢", minWidth: 100},
+      {
+        prop: "payableType", label: "浠樻绫诲瀷", minWidth: 100,
+        formatter: (row) => {
+          if (row.payableType == null) {
+            return ""
+          }
+          const dictItem = dictStore.getDictDataByTypeAndValue("payable_type", row.payableType);
+          return dictItem ? dictItem.label : "";
+        }
+      },
+      {
+        prop: "registrantId", label: "褰曞叆浜�", minWidth: 100,
+        formatter: (row) => {
+          // 鍖归厤鐢ㄦ埛淇℃伅
+          const user = userList.value.find((user) => user.userId === row.registrantId);
+          return user ? user.nickName : "鏈煡鐢ㄦ埛";
+        },
+      },
+      {prop: "registrationDate", label: "褰曞叆鏃ユ湡", minWidth: 100},
+    ],
+  }
+};
+
+
+// 褰撳墠鏍囩椤甸厤缃�
+const currentTabConfig = computed(() => tabsConfig[activeTab.value]);
+
+// 璁$畻灞炴��
+const searchPlaceholder = computed(
+    () => currentTabConfig.value?.searchPlaceholder || "璇疯緭鍏ユ悳绱俊鎭�"
+);
+const shouldShowSearch = computed(
+    () => currentTabConfig.value?.showSearch || false
+);
+const columns = computed(() => currentTabConfig.value?.columns || []);
+const selectedCount = computed(() => selectedRows.value.length);
+
+
+// 鍔ㄦ�佽幏鍙栨搷浣滃垪瀹藉害
+const getOperationsWidth = () => {
+  if (activeTab.value === 'equipmentRequisition') {
+    return 250; // 涓哄綊杩樻寜閽鐣欐洿澶氱┖闂�
+  }
+  return 200; // 榛樿瀹藉害
+};
+
+
+</script>
+
+<style scoped>
+/* 鍝嶅簲寮忓竷灞� */
+@media screen and (min-width: 768px) {
+  .search-form :deep(.el-form-item) {
+    width: 50%;
+  }
+}
+
+@media screen and (min-width: 1200px) {
+  .search-form :deep(.el-form-item) {
+    width: 16%;
+  }
+}
+
+.table-toolbar {
+  margin-bottom: 20px;
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.app-container {
+  padding: 18px !important;
+}
+
+/* 鍝嶅簲寮忚〃鏍� */
+@media screen and (max-width: 768px) {
+  .table-toolbar {
+    flex-direction: column;
+  }
+
+  .table-toolbar .el-button {
+    width: 100%;
+  }
+}
+
+/* 琛ㄦ牸宸ュ叿鏍� */
+.table-toolbar,
+.table-toolbar > * {
+  margin: 0 0 0 0 !important;
+}
+
+.table-toolbar {
+  margin-bottom: 20px !important;
+}
+
+.el-form--inline .el-form-item {
+  margin-right: 25px;
+}
+
+.main-container {
+  background: red !important;
+}
+
+/* 璁惧鐘舵�佹牱寮� */
+.status-using {
+  color: #409eff;
+  font-weight: 500;
+}
+
+.status-partial-return {
+  color: #e6a23c;
+  font-weight: 500;
+}
+
+.status-returned {
+  color: #67c23a;
+  font-weight: 500;
+}
+
+.status-unknown {
+  color: #909399;
+  font-weight: 500;
+}
+
+/* 鐘舵�佹爣绛炬牱寮� */
+:deep(.el-table .cell .status-tag) {
+  font-size: 12px;
+  padding: 2px 6px;
+  border-radius: 4px;
+  white-space: nowrap;
+}
+</style>
diff --git a/src/views/procureMent/components/ProductionDialog.vue b/src/views/procureMent/components/ProductionDialog.vue
index 859cbea..8ff7942 100644
--- a/src/views/procureMent/components/ProductionDialog.vue
+++ b/src/views/procureMent/components/ProductionDialog.vue
@@ -145,6 +145,20 @@
             value-format="YYYY-MM-DD"
           />
         </el-form-item>
+          <el-form-item label="绫诲瀷" prop="purchaseType">
+          <el-select
+              v-model="form.purchaseType"
+              placeholder="璇烽�夋嫨绫诲瀷"
+              :disabled="isViewMode"
+          >
+            <el-option
+                v-for="item in purchaseTypeList"
+                :key="item.value"
+                :label="item.label"
+                :value="Number(item.value)"
+            />
+          </el-select>
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -171,6 +185,7 @@
 import { ElMessage } from "element-plus";
 import useUserStore from "@/store/modules/user";
 import { addOrEditPR, getSupplyList, getCoalInfoList } from "@/api/procureMent";
+import useDictStore from "@/store/modules/dict"
 
 const props = defineProps({
   title: {
@@ -193,8 +208,9 @@
 });
 const supplyList = ref([]);
 const coalList = ref([]);
+const purchaseTypeList = ref([])
 const isViewMode = computed(() => props.title.includes("鏌ョ湅"));
-// 鑾峰彇渚涘簲鍟嗕笅鎷夊拰鐓ょ涓嬫媺
+// 鑾峰彇渚涘簲鍟嗕笅鎷夊拰鐓ょ涓嬫媺 浠ュ強绫诲瀷
 const getDropdownData = async () => {
   try {
     const [supplyRes, coalRes] = await Promise.all([
@@ -211,6 +227,7 @@
       value: item.id,
       label: item.coal,
     }));
+
   } catch (error) {
     ElMessage.error("鑾峰彇涓嬫媺鏁版嵁澶辫触锛岃绋嶅悗閲嶈瘯");
   }
@@ -333,12 +350,19 @@
 };
 
 onMounted(async () => {
+
+  purchaseTypeList.value = useDictStore().getDictTypeList("purchase_type").map((item) => ({
+    value: item.value,
+    label: item.label,
+  }))
+
   let res = await userStore.getInfo();
   userInfo.value = res.user;
   await getDropdownData();
   // 缁勪欢鍔犺浇瀹屾垚鍚庤Е鍙戜竴娆¤绠�
   calculatePrices();
 });
+
 const rules = {
   supplierName: [
     { required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" },
@@ -358,6 +382,9 @@
     { required: true, message: "璇疯緭鍏ョ◣鐜�", trigger: "blur" },
     { type: "number", message: "绋庣巼蹇呴』涓烘暟瀛�", trigger: "blur" },
   ],
+  purchaseType: [
+    { required: true, message: "璇烽�夋嫨绫诲瀷", trigger: "change" }
+  ]
 };
 // 鍏抽棴寮圭獥
 const handleClose = () => {
diff --git a/src/views/procureMent/index.vue b/src/views/procureMent/index.vue
index 159c0fc..d95dcbf 100644
--- a/src/views/procureMent/index.vue
+++ b/src/views/procureMent/index.vue
@@ -16,9 +16,12 @@
     </el-form>
     <el-card>
       <!-- 鎿嶄綔鎸夐挳鍖� -->
-      <el-row :gutter="24" class="table-toolbar">
+      <el-row :gutter="24" class="table-toolbar" justify="space-between">
         <el-button type="primary" :icon="Plus" @click="handleAdd"
           >鏂板缓
+        </el-button>
+        <el-button type="primary" :icon="Plus" @click="handleAddPayable">
+          娣诲姞搴斾粯娆�
         </el-button>
         <!-- <el-button type="danger" :icon="Delete" @click="handleDelete"
           >鍒犻櫎
@@ -59,6 +62,14 @@
       @success="handleSuccess"
       ref="productionDialogs"
     />
+    <PayableDialog
+        v-model:dialogPayableFormVisible="dialogPayableFormVisible"
+        v-model:form="formPayable"
+        :title="title"
+        @submit="handleSubmit"
+        @success="payableHandleSuccess"
+        ref="productionDialogs">
+    </PayableDialog>>
   </div>
 </template>
 
@@ -69,6 +80,8 @@
 import DataTable from "@/components/Table/ETable.vue";
 import Pagination from "@/components/Pagination";
 import ProductionDialog from "./components/ProductionDialog.vue";
+import PayableDialog from "../payable/components/PayableDialog.vue";
+
 import {
   purchaseRegistration,
   getSupplyList,
@@ -77,14 +90,20 @@
 } from "@/api/procureMent";
 import { useDelete } from "@/hooks/useDelete";
 const userStore = useUserStore();
+const dictStore = useDictStore()
 import useUserStore from "@/store/modules/user";
+import useDictStore from "@/store/modules/dict"
+
 let userList = ref([]);
 userStore.getUserList().then((res) => {
   userList.value = res;
 });
+
 // 寮曞叆瀛楀吀鏁版嵁
+
 const { proxy } = getCurrentInstance();
 const dialogFormVisible = ref(false);
+const dialogPayableFormVisible = ref(false);
 const form = ref({
   taxRate: 13,
   freight: 20,
@@ -97,6 +116,7 @@
 const pageSize = ref(10);
 const selectedRows = ref([]);
 const copyForm = ref({});
+const formPayable = ref({});
 // 鏌ヨ鍙傛暟
 const queryParams = reactive({
   searchAll: "",
@@ -165,6 +185,14 @@
       return user ? user.nickName : "鏈煡鐢ㄦ埛";
     },
   },
+  { prop: "purchaseType", label: "绫诲瀷", minWidth: 100 ,
+    formatter: (row) => {
+      if (row.purchaseType == null) {
+        return ""
+      }
+      const dictItem = dictStore.getDictDataByTypeAndValue("purchase_type", row.purchaseType);
+      return dictItem ? dictItem.label : "";    }
+  },
   { prop: "registrationDate", label: "鐧昏鏃ユ湡", minWidth: 100 },
 ]);
 
@@ -195,6 +223,28 @@
   addOrEdit.value = "add";
   handleAddEdit();
 };
+const handleAddPayable = () => {
+  // 鍙湁閫夋嫨涓�琛岀殑鏃跺�欒繘琛屾搷浣�
+
+  if (selectedRows.value.length !== 1) {
+    ElMessage.error("璇烽�変腑涓�琛岃繘琛屽~鍐�")
+    return
+  }
+
+  formPayable.value = {
+    purchaseRegistrationId: selectedRows.value[0].id,
+    registrantId: userInfo.value.userId,
+    ticketNo:"",
+    paymentAmount:"",
+    payableType:"",
+    attachUpload:"",
+    registrationDate: new Date().toISOString().split("T")[0],
+    fileList:[]
+  }
+  dialogPayableFormVisible.value = true
+
+};
+
 // 鏂板缂栬緫
 const productionDialogs = ref(null); // 娣诲姞ref澹版槑
 
@@ -212,7 +262,6 @@
     // 瑙﹀彂ref閲岄潰鐨勬柟娉�
     return;
   }
-  console.log(userInfo.value)
   // 鏂板缓鏃跺垵濮嬪寲琛ㄥ崟
   form.value = {
     supplierName: "",
@@ -227,6 +276,7 @@
     freight:20,
     registrantId: userInfo.value.userId,
     registrationDate: new Date().toISOString().split("T")[0],
+    purchaseType: ""
   };
   // 鏂板缓鏃朵篃闇�瑕佽缃� copyForm 鐢ㄤ簬閲嶇疆鍔熻兘
   copyForm.value = JSON.parse(JSON.stringify(form.value));
@@ -278,6 +328,12 @@
   total.value = tableData.value.length;
   ElMessage.success("鎿嶄綔鎴愬姛");
 };
+
+const payableHandleSuccess = (val) => {
+  ElMessage.success("鎿嶄綔鎴愬姛");
+  dialogPayableFormVisible.value = false;
+}
+
 const getList = async () => {
   loading.value = true;
   try {

--
Gitblit v1.9.3