From c1afd811abb7879a2b7359e419ce99d52235ded9 Mon Sep 17 00:00:00 2001 From: maven <2163098428@qq.com> Date: 星期四, 07 八月 2025 10:01:12 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev_7004' into dev_7004 --- src/views/financialManagement/expenseManagement/Modal.vue | 69 ++ src/assets/styles/element-ui.scss | 18 src/views/financialManagement/revenueManagement/index.vue | 279 +++++++++ src/api/financialManagement/expenseManagement.js | 78 ++ src/views/financialManagement/revenueManagement/Modal.vue | 69 ++ src/views/financialManagement/expenseManagement/Form.vue | 123 ++++ src/views/financialManagement/revenueManagement/filesDia.vue | 202 +++++++ src/views/financialManagement/expenseManagement/index.vue | 279 +++++++++ src/api/financialManagement/revenueManagement.js | 78 ++ src/main.js | 129 ++-- package.json | 2 src/views/financialManagement/revenueManagement/Form.vue | 123 ++++ src/views/salesManagement/salesLedger/fileList.vue | 9 src/components/filePreview/index.vue | 202 +++++++ src/views/financialManagement/financialStatements/index.vue | 4 15 files changed, 1,596 insertions(+), 68 deletions(-) diff --git a/package.json b/package.json index 871409b..15334fa 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,8 @@ }, "dependencies": { "@element-plus/icons-vue": "2.3.1", + "@vue-office/docx": "^1.6.3", + "@vue-office/excel": "^1.7.14", "@vueup/vue-quill": "1.2.0", "@vueuse/core": "10.11.0", "axios": "0.28.1", diff --git a/src/api/financialManagement/expenseManagement.js b/src/api/financialManagement/expenseManagement.js new file mode 100644 index 0000000..317dc47 --- /dev/null +++ b/src/api/financialManagement/expenseManagement.js @@ -0,0 +1,78 @@ +import request from "@/utils/request"; + +// 鏌ヨ鍒楄〃 +export const listPage = (params) => { + return request({ + url: "/account/accountExpense/listPage", + method: "get", + params, + }); +}; + +// 鏂板 +export function add(data) { + return request({ + url: "/account/accountExpense/add", + method: "post", + data: data, + }); +} + +// 缂栬緫 +export function update(data) { + return request({ + url: "/account/accountExpense/update", + method: "post", + data: data, + }); +} + +//瀵煎嚭 +export const exportAccountExpense = (query) => { + return request({ + url: "/account/accountExpense/export", + method: "post", + data: query, + responseType: "blob", + }); +}; + +export const delAccountExpense = (query) => { + return request({ + url: `account/accountExpense/del`, + method: "delete", + data: query, + }); +}; + +export const getAccountExpense = (id) => { + return request({ + url: `/account/accountExpense/${id}`, + method: "get", + }); +}; + +// 鏌ヨ闄勪欢鍒楄〃 +export function fileListPage(query) { + return request({ + url: "/account/accountFile/listPage", + method: "get", + params: query, + }); +} +// 淇濆瓨闄勪欢鍒楄〃 +export function fileAdd(query) { + return request({ + url: "/account/accountFile/add", + method: "post", + data: query, + }); +} +// 鍒犻櫎闄勪欢鍒楄〃 +export function fileDel(query) { + return request({ + url: "/account/accountFile/del", + method: "delete", + data: query, + }); +} diff --git a/src/api/financialManagement/revenueManagement.js b/src/api/financialManagement/revenueManagement.js new file mode 100644 index 0000000..090ddf8 --- /dev/null +++ b/src/api/financialManagement/revenueManagement.js @@ -0,0 +1,78 @@ +import request from "@/utils/request"; + +// 鏌ヨ鍒楄〃 +export const listPage = (params) => { + return request({ + url: "/account/accountIncome/listPage", + method: "get", + params, + }); +}; + +// 鏂板 +export function add(data) { + return request({ + url: "/account/accountIncome/add", + method: "post", + data: data, + }); +} + +// 缂栬緫 +export function update(data) { + return request({ + url: "/account/accountIncome/update", + method: "post", + data: data, + }); +} + +//瀵煎嚭 +export const exportAccountIncome = (query) => { + return request({ + url: "/account/accountIncome/export", + method: "post", + data: query, + responseType: "blob", + }); +}; + +export const delAccountIncome = (query) => { + return request({ + url: `account/accountIncome/del`, + method: "delete", + data: query, + }); +}; + +export const getAccountIncome = (id) => { + return request({ + url: `/account/accountIncome/${id}`, + method: "get", + }); +}; + +// 鏌ヨ闄勪欢鍒楄〃 +export function fileListPage(query) { + return request({ + url: "/account/accountFile/listPage", + method: "get", + params: query, + }); +} +// 淇濆瓨闄勪欢鍒楄〃 +export function fileAdd(query) { + return request({ + url: "/account/accountFile/add", + method: "post", + data: query, + }); +} +// 鍒犻櫎闄勪欢鍒楄〃 +export function fileDel(query) { + return request({ + url: "/account/accountFile/del", + method: "delete", + data: query, + }); +} diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss index 0c4c3de..4eae8b2 100644 --- a/src/assets/styles/element-ui.scss +++ b/src/assets/styles/element-ui.scss @@ -56,18 +56,18 @@ padding: 0 !important; } .el-dialog__header { - background: #F5F6F7; + background: #f5f6f7; padding: 12px 16px; border-radius: 8px 8px 0 0; } .el-dialog__title { font-weight: 400; font-size: 16px; - color: #2E3033; + color: #2e3033; } .el-dialog__body { padding: 16px 40px 0 40px; - max-height: 680px; + max-height: 90vh; overflow-y: auto; } .el-dialog__footer { @@ -79,14 +79,14 @@ border-radius: 8px; } .el-message-box__header { - background: #F5F6F7; + background: #f5f6f7; padding: 12px 16px; border-radius: 8px 8px 0 0; } .el-message-box__title { font-weight: 400; font-size: 16px; - color: #2E3033; + color: #2e3033; } .el-message-box__content { padding: 16px 40px 0 40px; @@ -108,7 +108,7 @@ .el-table__expanded-cell { padding: 0 !important; .el-table__header-wrapper { - background-color: #F5F8FF !important; + background-color: #f5f8ff !important; } } @@ -127,7 +127,7 @@ // dropdown .el-dropdown-menu { a { - display: block + display: block; } } @@ -149,6 +149,6 @@ display: none; } -.el-dropdown .el-dropdown-link{ +.el-dropdown .el-dropdown-link { color: var(--el-color-primary) !important; -} \ No newline at end of file +} diff --git a/src/components/filePreview/index.vue b/src/components/filePreview/index.vue new file mode 100644 index 0000000..cda5b56 --- /dev/null +++ b/src/components/filePreview/index.vue @@ -0,0 +1,202 @@ +<template> + <el-dialog v-model="dialogVisible" title="棰勮" width="100%" fullscreen align-center :before-close="handleClose" append-to-body> + <div> + <!-- 鍥剧墖棰勮 --> + <div v-if="isImage"> + <img :src="imgUrl" alt="Image Preview" /> + </div> + + <!-- PDF棰勮鎻愮ず --> + <div v-if="isPdf" style="height: 100vh; display: flex; align-items: center; justify-content: center;"> + <p>姝e湪鍑嗗PDF棰勮...</p> + </div> + + <!-- Word鏂囨。棰勮 --> + <div v-if="isDoc"> + <p v-if="!isDocShow">鏂囨。鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p> + <a :href="fileUrl" v-if="!isDocShow">涓嬭浇鏂囦欢</a> + <vue-office-docx + v-else + :src="fileUrl" + style="height: 100vh;" + @rendered="renderedHandler" + @error="errorHandler" + /> + </div> + + <!-- Excel鏂囨。棰勮 --> + <div v-if="isXls"> + <p v-if="!isDocShow">鏂囨。鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p> + <a :href="fileUrl" v-if="!isDocShow">涓嬭浇鏂囦欢</a> + <vue-office-excel + v-else + :src="fileUrl" + :options="options" + style="height: 100vh;" + @rendered="renderedHandler" + @error="errorHandler" + /> + </div> + + <!-- 鍘嬬缉鏂囦欢澶勭悊 --> + <div v-if="isZipOrRar"> + <p>鍘嬬缉鏂囦欢鏃犳硶鐩存帴棰勮锛岃涓嬭浇鏌ョ湅銆�</p> + <a :href="fileUrl">涓嬭浇鏂囦欢</a> + </div> + + <!-- 涓嶆敮鎸佺殑鏍煎紡 --> + <div v-if="!isSupported"> + <p>涓嶆敮鎸佺殑鏂囦欢鏍煎紡</p> + </div> + </div> + </el-dialog> +</template> + +<script setup> +import { ref, computed, getCurrentInstance, watch } from 'vue'; +import VueOfficeDocx from '@vue-office/docx'; +import '@vue-office/docx/lib/index.css'; +import VueOfficeExcel from '@vue-office/excel'; +import '@vue-office/excel/lib/index.css'; + +// 鍝嶅簲寮忓彉閲� +const fileUrl = ref('') +const dialogVisible = ref(false) +const { proxy } = getCurrentInstance(); +const javaApi = proxy.javaApi; + +// 鏂囨。棰勮鐘舵�� +const isDocShow = ref(true); +const imgUrl = ref(''); +const options = ref({ + xls: false, + minColLength: 0, + minRowLength: 0, + widthOffset: 10, + heightOffset: 10, + beforeTransformData: (workbookData) => workbookData, + transformData: (workbookData) => workbookData, +}); + +// 璁$畻灞炴�� - 鍒ゆ柇鏂囦欢绫诲瀷 +const isImage = computed(() => { + const state = /\.(jpg|jpeg|png|gif)$/i.test(fileUrl.value); + if (state) { + imgUrl.value = fileUrl.value.replaceAll('word', 'img'); + } + return state; +}); + +const isPdf = computed(() => { + console.log(fileUrl.value) + return /\.pdf$/i.test(fileUrl.value); +}); + +const isDoc = computed(() => { + return /\.(doc|docx)$/i.test(fileUrl.value); +}); + +const isXls = computed(() => { + const state = /\.(xls|xlsx)$/i.test(fileUrl.value); + if (state) { + options.value.xls = /\.(xls)$/i.test(fileUrl.value); + } + return state; +}); + +const isZipOrRar = computed(() => { + return /\.(zip|rar)$/i.test(fileUrl.value); +}); + +const isSupported = computed(() => { + return isImage.value || isPdf.value || isDoc.value || isXls.value || isZipOrRar.value; +}); + +// 鍔ㄦ�佸垱寤篴鏍囩骞惰烦杞瑙圥DF +const previewPdf = (url) => { + // 鍒涘缓a鏍囩 + const link = document.createElement('a'); + // 璁剧疆PDF鏂囦欢URL + link.href = url; + // 鍦ㄦ柊鏍囩椤垫墦寮� + link.target = '_blank'; + // 瀹夊叏灞炴�э紝闃叉鏂伴〉闈㈣闂師椤甸潰 + link.rel = 'noopener noreferrer'; + // 鍙�夛細璁剧疆閾炬帴鏂囨湰 + link.textContent = '棰勮PDF'; + // 灏哸鏍囩娣诲姞鍒伴〉闈紙閮ㄥ垎娴忚鍣ㄨ姹傚繀椤诲湪DOM涓級 + document.body.appendChild(link); + // 瑙﹀彂鐐瑰嚮浜嬩欢 + link.click(); + // 绉婚櫎a鏍囩锛屾竻鐞咲OM + document.body.removeChild(link); +}; + + +// 鐩戝惉PDF鐘舵�佸彉鍖栵紝鑷姩瑙﹀彂璺宠浆 +watch( + () => isPdf.value, + (newVal) => { + + // 褰撶‘璁ゆ槸PDF涓旀枃浠禪RL鏈夋晥鏃� + if (newVal && fileUrl.value) { + // 鍏抽棴瀵硅瘽妗� + dialogVisible.value = false; + // 鍔犱釜灏忓欢杩熺‘淇濈姸鎬佹洿鏂板畬鎴� + setTimeout(() => { + previewPdf(fileUrl.value); + fileUrl.value = ''; + }, 100); + } + } +); + +// 鏂规硶瀹氫箟 +const renderedHandler = () => { + console.log("娓叉煋瀹屾垚"); + isDocShow.value = true; + resetStyle(); +}; + +const errorHandler = () => { + console.log("娓叉煋澶辫触"); + isDocShow.value = false; +}; + +const open = (url) => { + fileUrl.value = window.location.protocol+'//'+window.location.host+ url; + dialogVisible.value = true; +}; +const handleClose = () => { + dialogVisible.value = false; +}; + +const resetStyle = () => { + const elements = document.querySelectorAll('[style*="pt"]'); + for (const element of elements) { + const style = element.getAttribute('style'); + if (style) { + element.setAttribute('style', style.replace(/pt/g, 'px')); + } + } +}; + +// 鏆撮湶open鏂规硶渚涘閮ㄨ皟鐢� +defineExpose({ + open +}) +</script> + +<style scoped> +img { + max-width: 100%; + display: block; + margin: 0 auto; +} + +.oneLine { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +</style> diff --git a/src/main.js b/src/main.js index 48ee15c..014954c 100644 --- a/src/main.js +++ b/src/main.js @@ -1,68 +1,81 @@ -import { createApp } from 'vue' +import { createApp } from "vue"; -import Cookies from 'js-cookie' +import Cookies from "js-cookie"; -import ElementPlus from 'element-plus' -import 'element-plus/dist/index.css' -import 'element-plus/theme-chalk/dark/css-vars.css' -import locale from 'element-plus/es/locale/lang/zh-cn' +import ElementPlus from "element-plus"; +import "element-plus/dist/index.css"; +import "element-plus/theme-chalk/dark/css-vars.css"; +import locale from "element-plus/es/locale/lang/zh-cn"; -import '@/assets/styles/index.scss' // global css +import "@/assets/styles/index.scss"; // global css -import App from './App' -import store from './store' -import router from './router' -import directive from './directive' // directive +import App from "./App"; +import store from "./store"; +import router from "./router"; +import directive from "./directive"; // directive // 娉ㄥ唽鎸囦护 -import plugins from './plugins' // plugins -import { download } from '@/utils/request' +import plugins from "./plugins"; // plugins +import { download } from "@/utils/request"; // svg鍥炬爣 -import 'virtual:svg-icons-register' -import SvgIcon from '@/components/SvgIcon' -import elementIcons from '@/components/SvgIcon/svgicon' +import "virtual:svg-icons-register"; +import SvgIcon from "@/components/SvgIcon"; +import elementIcons from "@/components/SvgIcon/svgicon"; -import './permission' // permission control +import "./permission"; // permission control -import { useDict } from '@/utils/dict' -import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi' +import { useDict } from "@/utils/dict"; +import { + parseTime, + resetForm, + addDateRange, + handleTree, + selectDictLabel, + selectDictLabels, +} from "@/utils/ruoyi"; // 鍒嗛〉缁勪欢 -import Pagination from '@/components/Pagination' +import Pagination from "@/components/Pagination"; // 鑷畾涔夎〃鏍煎伐鍏风粍浠� -import RightToolbar from '@/components/RightToolbar' +import RightToolbar from "@/components/RightToolbar"; // 瀵屾枃鏈粍浠� -import Editor from "@/components/Editor" +import Editor from "@/components/Editor"; // 鏂囦欢涓婁紶缁勪欢 -import FileUpload from "@/components/FileUpload" +import FileUpload from "@/components/FileUpload"; // 鍥剧墖涓婁紶缁勪欢 -import ImageUpload from "@/components/ImageUpload" +import ImageUpload from "@/components/ImageUpload"; // 鍥剧墖棰勮缁勪欢 -import ImagePreview from "@/components/ImagePreview" +import ImagePreview from "@/components/ImagePreview"; // 瀛楀吀鏍囩缁勪欢 -import DictTag from '@/components/DictTag' +import DictTag from "@/components/DictTag"; // 琛ㄦ牸缁勪欢 import PIMTable from "@/components/PIMTable/PIMTable.vue"; import { getToken } from "@/utils/auth"; -import {calculateTaxExclusiveTotalPrice, summarizeTable,calculateTaxIncludeTotalPrice} from "@/utils/summarizeTable.js"; +import { + calculateTaxExclusiveTotalPrice, + summarizeTable, + calculateTaxIncludeTotalPrice, +} from "@/utils/summarizeTable.js"; -const app = createApp(App) +const app = createApp(App); // 鍏ㄥ眬鏂规硶鎸傝浇 -app.config.globalProperties.useDict = useDict -app.config.globalProperties.download = download -app.config.globalProperties.parseTime = parseTime -app.config.globalProperties.resetForm = resetForm -app.config.globalProperties.summarizeTable = summarizeTable -app.config.globalProperties.calculateTaxExclusiveTotalPrice = calculateTaxExclusiveTotalPrice -app.config.globalProperties.calculateTaxIncludeTotalPrice = calculateTaxIncludeTotalPrice -app.config.globalProperties.handleTree = handleTree -app.config.globalProperties.addDateRange = addDateRange -app.config.globalProperties.selectDictLabel = selectDictLabel -app.config.globalProperties.selectDictLabels = selectDictLabels -app.config.globalProperties.javaApi = 'http://114.132.189.42:8078' +app.config.globalProperties.useDict = useDict; +app.config.globalProperties.download = download; +app.config.globalProperties.parseTime = parseTime; +app.config.globalProperties.resetForm = resetForm; +app.config.globalProperties.summarizeTable = summarizeTable; +app.config.globalProperties.calculateTaxExclusiveTotalPrice = + calculateTaxExclusiveTotalPrice; +app.config.globalProperties.calculateTaxIncludeTotalPrice = + calculateTaxIncludeTotalPrice; +app.config.globalProperties.handleTree = handleTree; +app.config.globalProperties.addDateRange = addDateRange; +app.config.globalProperties.selectDictLabel = selectDictLabel; +app.config.globalProperties.selectDictLabels = selectDictLabels; +app.config.globalProperties.javaApi = "http://114.132.189.42:8099"; app.config.globalProperties.HaveJson = (val) => { return JSON.parse(JSON.stringify(val)); }; @@ -71,29 +84,29 @@ }; // 鍏ㄥ眬缁勪欢鎸傝浇 -app.component('DictTag', DictTag) -app.component('Pagination', Pagination) -app.component('FileUpload', FileUpload) -app.component('ImageUpload', ImageUpload) -app.component('ImagePreview', ImagePreview) -app.component('RightToolbar', RightToolbar) -app.component('Editor', Editor) -app.component('PIMTable', PIMTable) +app.component("DictTag", DictTag); +app.component("Pagination", Pagination); +app.component("FileUpload", FileUpload); +app.component("ImageUpload", ImageUpload); +app.component("ImagePreview", ImagePreview); +app.component("RightToolbar", RightToolbar); +app.component("Editor", Editor); +app.component("PIMTable", PIMTable); -app.use(router) -app.use(store) -app.use(plugins) -app.use(elementIcons) -app.component('svg-icon', SvgIcon) +app.use(router); +app.use(store); +app.use(plugins); +app.use(elementIcons); +app.component("svg-icon", SvgIcon); -directive(app) +directive(app); // 浣跨敤element-plus 骞朵笖璁剧疆鍏ㄥ眬鐨勫ぇ灏� app.use(ElementPlus, { locale: locale, // 鏀寔 large銆乨efault銆乻mall - size: Cookies.get('size') || 'default' -}) -app._context.components.ElDialog.props.closeOnClickModal.default = false + size: Cookies.get("size") || "default", +}); +app._context.components.ElDialog.props.closeOnClickModal.default = false; -app.mount('#app') +app.mount("#app"); diff --git a/src/views/financialManagement/expenseManagement/Form.vue b/src/views/financialManagement/expenseManagement/Form.vue new file mode 100644 index 0000000..9cfe5da --- /dev/null +++ b/src/views/financialManagement/expenseManagement/Form.vue @@ -0,0 +1,123 @@ +<template> + <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef"> + <el-form-item label="鏀嚭鏃ユ湡" prop="expenseDate"> + <el-date-picker + style="width: 100%" + v-model="form.expenseDate" + format="YYYY-MM-DD" + value-format="YYYY-MM-DD" + type="date" + placeholder="璇烽�夋嫨鏃ユ湡" + clearable + /> + </el-form-item> + <el-form-item label="鏀嚭绫诲瀷" prop="expenseType"> + <el-select + v-model="form.expenseType" + placeholder="璇烽�夋嫨" + clearable + > + <el-option :label="item.label" :value="item.value" v-for="(item,index) in expense_types" :key="index" /> + </el-select> + </el-form-item> + <el-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName"> + <el-input v-model="form.supplierName" placeholder="璇疯緭鍏�" /> + </el-form-item> + <el-form-item label="鏀嚭閲戦" prop="expenseMoney"> + <el-input-number :step="0.01" :min="0" style="width: 100%" + v-model="form.expenseMoney" + placeholder="璇疯緭鍏�" + /> + </el-form-item> + <el-form-item label="鏀嚭鎻忚堪" prop="expenseDescribed"> + <el-input v-model="form.expenseDescribed" placeholder="璇疯緭鍏�" /> + </el-form-item> + <el-form-item label="浠樻鏂瑰紡" prop="expenseMethod"> + <el-select + v-model="form.expenseMethod" + placeholder="璇烽�夋嫨" + clearable + > + <el-option :label="item.label" :value="item.value" v-for="(item,index) in checkout_payment" :key="index" /> + </el-select> + </el-form-item> + <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNumber"> + <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" /> + </el-form-item> + <el-form-item label="澶囨敞" prop="note"> + <el-input + v-model="form.note" + placeholder="澶囨敞" + /> + </el-form-item> + + </el-form> +</template> + +<script setup> +import useFormData from "@/hooks/useFormData"; +import { getAccountExpense } from "@/api/financialManagement/expenseManagement"; +import {ref} from "vue"; +const { proxy } = getCurrentInstance(); + + +defineOptions({ + name: "鏂板鏀嚭", +}); +const { expense_types } = proxy.useDict("expense_types"); +const { checkout_payment } = proxy.useDict("checkout_payment"); +const formRef = ref(null); +const formRules = { + supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }], + expenseMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }], + expenseDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }], + expenseDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }], + expenseType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }], + expenseMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }], +} + +const { form, resetForm } = useFormData({ + expenseDate: undefined, // 鏀嚭鏃ユ湡 + expenseType: undefined, // 鏀嚭绫诲瀷 + supplierName: undefined, // 瀹㈡埛鍚嶇О + expenseMoney: undefined, // 鏀嚭閲戦 + expenseDescribed: undefined, // 鏀嚭鎻忚堪 + expenseMethod: undefined, // 鏀舵鏂瑰紡 + invoiceNumber: undefined, // 鍙戠エ鍙风爜 + note: undefined, // 澶囨敞 +}); + +const loadForm = async (id) => { + const { code, data } = await getAccountExpense(id); + if (code == 200) { + form.expenseDate = data.expenseDate; + form.expenseType = data.expenseType; + form.supplierName = data.supplierName; + form.expenseMoney = data.expenseMoney; + form.expenseDescribed = data.expenseDescribed; + form.expenseMethod = data.expenseMethod; + form.invoiceNumber = data.invoiceNumber; + form.note = data.note; + } +}; + +// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵�� +const clearValidate = () => { + formRef.value?.clearValidate(); +}; + +// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬� +const resetFormAndValidate = () => { + resetForm(); + clearValidate(); +}; + +defineExpose({ + form, + loadForm, + resetForm, + clearValidate, + resetFormAndValidate, + formRef, +}); +</script> diff --git a/src/views/financialManagement/expenseManagement/Modal.vue b/src/views/financialManagement/expenseManagement/Modal.vue new file mode 100644 index 0000000..8e5b171 --- /dev/null +++ b/src/views/financialManagement/expenseManagement/Modal.vue @@ -0,0 +1,69 @@ +<template> + <el-dialog :title="modalOptions.title" v-model="visible" @close="close" width="30%"> + <Form ref="formRef"></Form> + <template #footer> + <el-button type="primary" @click="sendForm" :loading="loading"> + {{ modalOptions.confirmText }} + </el-button> + <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> + </template> + </el-dialog> +</template> + +<script setup> +import { useModal } from "@/hooks/useModal"; +import { add, update } from "@/api/financialManagement/expenseManagement"; +import Form from "./Form.vue"; +import { ElMessage } from "element-plus"; +const { proxy } = getCurrentInstance() + +defineOptions({ + name: "鏀嚭鏂板缂栬緫", +}); + +const emits = defineEmits(["success"]); + +const formRef = ref(); +const { + id, + visible, + loading, + openModal, + modalOptions, + handleConfirm, + closeModal, +} = useModal({ title: "鏀嚭" }); + +const sendForm = () => { + proxy.$refs.formRef.$refs.formRef.validate(async valid => { + if (valid) { + const {code} = id.value + ? await update({id: id.value, ...formRef.value.form}) + : await add(formRef.value.form); + if (code == 200) { + emits("success"); + ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"}); + close(); + } else { + loading.value = false; + } + } + }) +}; + +const close = () => { + formRef.value.resetFormAndValidate(); + closeModal(); +}; + +const loadForm = async (id) => { + openModal(id); + await nextTick(); + formRef.value.loadForm(id); +}; + +defineExpose({ + openModal, + loadForm, +}); +</script> diff --git a/src/views/financialManagement/expenseManagement/index.vue b/src/views/financialManagement/expenseManagement/index.vue new file mode 100644 index 0000000..0c6cbde --- /dev/null +++ b/src/views/financialManagement/expenseManagement/index.vue @@ -0,0 +1,279 @@ +<template> + <div class="app-container"> + <el-form :model="filters" :inline="true"> + <el-form-item label="褰曞叆鏃ユ湡:"> + <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" + placeholder="璇烽�夋嫨" clearable @change="changeDaterange" /> + </el-form-item> + <el-form-item label="浠樻鏂瑰紡:"> + <el-select + v-model="filters.expenseMethod" + placeholder="璇烽�夋嫨" + clearable + style="width: 200px;" + > + <el-option + v-for="item in checkout_payment" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="getTableData">鎼滅储</el-button> + <el-button @click="resetFilters">閲嶇疆</el-button> + </el-form-item> + </el-form> + <div class="table_list"> + <div class="actions"> + <div></div> + <div> + <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button> + <el-button @click="handleOut" icon="download">瀵煎嚭</el-button> + <el-button + type="danger" + icon="Delete" + :disabled="multipleList.length <= 0" + @click="deleteRow(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" + @pagination="changePage" + > + <template #operation="{ row }"> + <el-button type="primary" text @click="edit(row.id)" icon="editPen"> + 缂栬緫 + </el-button> + <el-button + type="primary" + text + @click="openFilesFormDia(row)" + > + 闄勪欢 + </el-button> + </template> + </PIMTable> + </div> + <Modal ref="modalRef" @success="getTableData"></Modal> + <files-dia ref="filesDia" @close="handleQuery"></files-dia> + </div> +</template> + +<script setup> +import { usePaginationApi } from "@/hooks/usePaginationApi"; +import { listPage, delAccountExpense } from "@/api/financialManagement/expenseManagement"; +import { onMounted, getCurrentInstance } from "vue"; +import Modal from "./Modal.vue"; +import { ElMessageBox, ElMessage } from "element-plus"; +import dayjs from "dayjs"; +import FilesDia from "../revenueManagement/filesDia.vue"; + +defineOptions({ + name: "鏀嚭绠$悊", +}); + +// 琛ㄦ牸澶氶�夋閫変腑椤� +const multipleList = ref([]); +const { proxy } = getCurrentInstance(); +const modalRef = ref(); +const { checkout_payment } = proxy.useDict("checkout_payment"); +const { expense_types } = proxy.useDict("expense_types"); +const filesDia = ref() + +const { + filters, + columns, + dataList, + pagination, + getTableData, + resetFilters, + onCurrentChange, +} = usePaginationApi( + listPage, + { + expenseMethod: undefined, + }, + [ + { + label: "鏀嚭鏃ユ湡", + align: "center", + prop: "expenseDate", + }, + { + label: "鏀嚭绫诲瀷", + align: "center", + prop: "expenseType", + dataType: "tag", + formatData: (params) => { + if (expense_types.value.find((m) => m.value == params)) { + return expense_types.value.find((m) => m.value == params).label; + } else { + return null + } + }, + }, + { + label: "渚涘簲鍟嗗悕绉�", + align: "center", + prop: "supplierName", + + }, + { + label: "鏀嚭閲戦", + align: "center", + prop: "expenseMoney", + + }, + { + label: "鏀嚭鎻忚堪", + align: "center", + prop: "expenseDescribed", + + }, + { + label: "浠樻鏂瑰紡", + align: "center", + prop: "expenseMethod", + dataType: "tag", + formatData: (params) => { + if (checkout_payment.value.find((m) => m.value == params)) { + return checkout_payment.value.find((m) => m.value == params).label; + } else { + return null + } + }, + }, + { + label: "鍙戠エ鍙风爜", + align: "center", + prop: "invoiceNumber", + + }, + { + label: "澶囨敞", + align: "center", + prop: "note", + + }, + { + label: "褰曞叆浜�", + align: "center", + prop: "inputUser", + }, + { + label: "褰曞叆鏃ユ湡", + align: "center", + prop: "inputTime", + + }, + { + fixed: "right", + label: "鎿嶄綔", + dataType: "slot", + slot: "operation", + align: "center", + width: "200px", + }, + ] +); + +// 澶氶�夊悗鍋氫粈涔� +const handleSelectionChange = (selectionList) => { + multipleList.value = selectionList; +}; + +const add = () => { + modalRef.value.openModal(); +}; +const edit = (id) => { + modalRef.value.loadForm(id); +}; +const changePage = ({ page, limit }) => { + pagination.currentPage = page; + pagination.pageSize = limit; + onCurrentChange(page); +}; +const deleteRow = (id) => { + ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning", + }).then(async () => { + const { code } = await delAccountExpense(id); + if (code == 200) { + ElMessage({ + type: "success", + message: "鍒犻櫎鎴愬姛", + }); + getTableData(); + } + }); +}; + +const changeDaterange = (value) => { + if (value) { + filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); + filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); + } else { + filters.entryDateStart = undefined; + filters.entryDateEnd = undefined; + } + getTableData(); +}; + +const handleOut = () => { + ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", { + confirmButtonText: "纭", + cancelButtonText: "鍙栨秷", + type: "warning", + }) + .then(() => { + proxy.download(`/account/accountExpense/export`, {}, "鏀嚭鍙拌处.xlsx"); + }) + .catch(() => { + proxy.$modal.msg("宸插彇娑�"); + }); +}; +// 鎵撳紑闄勪欢寮规 +const openFilesFormDia = (row) => { + nextTick(() => { + filesDia.value?.openDialog( row,'鏀嚭') + }) +}; + +onMounted(() => { + filters.entryDate = [ + dayjs().format("YYYY-MM-DD"), + dayjs().add(1, "day").format("YYYY-MM-DD"), + ] + filters.entryDateStart = dayjs().format("YYYY-MM-DD") + filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD") + getTableData(); +}); +</script> + +<style lang="scss" scoped> +.table_list { + margin-top: unset; +} +.actions { + display: flex; + justify-content: space-between; + margin-bottom: 10px; +} +</style> + diff --git a/src/views/financialManagement/financialStatements/index.vue b/src/views/financialManagement/financialStatements/index.vue new file mode 100644 index 0000000..c272707 --- /dev/null +++ b/src/views/financialManagement/financialStatements/index.vue @@ -0,0 +1,4 @@ +<template> +</template> +<script setup> +</script> \ No newline at end of file diff --git a/src/views/financialManagement/revenueManagement/Form.vue b/src/views/financialManagement/revenueManagement/Form.vue new file mode 100644 index 0000000..67b175e --- /dev/null +++ b/src/views/financialManagement/revenueManagement/Form.vue @@ -0,0 +1,123 @@ +<template> + <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef"> + <el-form-item label="鏀跺叆鏃ユ湡" prop="incomeDate"> + <el-date-picker + style="width: 100%" + v-model="form.incomeDate" + format="YYYY-MM-DD" + value-format="YYYY-MM-DD" + type="date" + placeholder="璇烽�夋嫨鏃ユ湡" + clearable + /> + </el-form-item> + <el-form-item label="鏀跺叆绫诲瀷" prop="incomeType"> + <el-select + v-model="form.incomeType" + placeholder="璇烽�夋嫨" + clearable + > + <el-option :label="item.label" :value="item.value" v-for="(item,index) in income_types" :key="index" /> + </el-select> + </el-form-item> + <el-form-item label="瀹㈡埛鍚嶇О" prop="customerName"> + <el-input v-model="form.customerName" placeholder="璇疯緭鍏�" /> + </el-form-item> + <el-form-item label="鏀跺叆閲戦" prop="incomeMoney"> + <el-input-number :step="0.01" :min="0" style="width: 100%" + v-model="form.incomeMoney" + placeholder="璇疯緭鍏�" + /> + </el-form-item> + <el-form-item label="鏀跺叆鎻忚堪" prop="incomeDescribed"> + <el-input v-model="form.incomeDescribed" placeholder="璇疯緭鍏�" /> + </el-form-item> + <el-form-item label="鏀舵鏂瑰紡" prop="incomeMethod"> + <el-select + v-model="form.incomeMethod" + placeholder="璇烽�夋嫨" + clearable + > + <el-option :label="item.label" :value="item.value" v-for="(item,index) in payment_methods" :key="index" /> + </el-select> + </el-form-item> + <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNumber"> + <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" /> + </el-form-item> + <el-form-item label="澶囨敞" prop="note"> + <el-input + v-model="form.note" + placeholder="澶囨敞" + /> + </el-form-item> + + </el-form> +</template> + +<script setup> +import useFormData from "@/hooks/useFormData"; +import { getAccountIncome } from "@/api/financialManagement/revenueManagement"; +import {ref} from "vue"; +const { proxy } = getCurrentInstance(); + + +defineOptions({ + name: "鏂板鏀跺叆", +}); +const { income_types } = proxy.useDict("income_types"); +const { payment_methods } = proxy.useDict("payment_methods"); +const formRef = ref(null); +const formRules = { + customerName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }], + incomeMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }], + incomeDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }], + incomeDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }], + incomeType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }], + incomeMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }], +} + +const { form, resetForm } = useFormData({ + incomeDate: undefined, // 鏀跺叆鏃ユ湡 + incomeType: undefined, // 鏀跺叆绫诲瀷 + customerName: undefined, // 瀹㈡埛鍚嶇О + incomeMoney: undefined, // 鏀跺叆閲戦 + incomeDescribed: undefined, // 鏀跺叆鎻忚堪 + incomeMethod: undefined, // 鏀舵鏂瑰紡 + invoiceNumber: undefined, // 鍙戠エ鍙风爜 + note: undefined, // 澶囨敞 +}); + +const loadForm = async (id) => { + const { code, data } = await getAccountIncome(id); + if (code == 200) { + form.incomeDate = data.incomeDate; + form.incomeType = data.incomeType; + form.customerName = data.customerName; + form.incomeMoney = data.incomeMoney; + form.incomeDescribed = data.incomeDescribed; + form.incomeMethod = data.incomeMethod; + form.invoiceNumber = data.invoiceNumber; + form.note = data.note; + } +}; + +// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵�� +const clearValidate = () => { + formRef.value?.clearValidate(); +}; + +// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬� +const resetFormAndValidate = () => { + resetForm(); + clearValidate(); +}; + +defineExpose({ + form, + loadForm, + resetForm, + clearValidate, + resetFormAndValidate, + formRef, +}); +</script> diff --git a/src/views/financialManagement/revenueManagement/Modal.vue b/src/views/financialManagement/revenueManagement/Modal.vue new file mode 100644 index 0000000..480b4fd --- /dev/null +++ b/src/views/financialManagement/revenueManagement/Modal.vue @@ -0,0 +1,69 @@ +<template> + <el-dialog :title="modalOptions.title" v-model="visible" @close="close" width="30%"> + <Form ref="formRef"></Form> + <template #footer> + <el-button type="primary" @click="sendForm" :loading="loading"> + {{ modalOptions.confirmText }} + </el-button> + <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> + </template> + </el-dialog> +</template> + +<script setup> +import { useModal } from "@/hooks/useModal"; +import { add, update } from "@/api/financialManagement/revenueManagement"; +import Form from "./Form.vue"; +import { ElMessage } from "element-plus"; +const { proxy } = getCurrentInstance() + +defineOptions({ + name: "鏀跺叆鏂板缂栬緫", +}); + +const emits = defineEmits(["success"]); + +const formRef = ref(); +const { + id, + visible, + loading, + openModal, + modalOptions, + handleConfirm, + closeModal, +} = useModal({ title: "鏀跺叆" }); + +const sendForm = () => { + proxy.$refs.formRef.$refs.formRef.validate(async valid => { + if (valid) { + const {code} = id.value + ? await update({id: id.value, ...formRef.value.form}) + : await add(formRef.value.form); + if (code == 200) { + emits("success"); + ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"}); + close(); + } else { + loading.value = false; + } + } + }) +}; + +const close = () => { + formRef.value.resetFormAndValidate(); + closeModal(); +}; + +const loadForm = async (id) => { + openModal(id); + await nextTick(); + formRef.value.loadForm(id); +}; + +defineExpose({ + openModal, + loadForm, +}); +</script> diff --git a/src/views/financialManagement/revenueManagement/filesDia.vue b/src/views/financialManagement/revenueManagement/filesDia.vue new file mode 100644 index 0000000..f752496 --- /dev/null +++ b/src/views/financialManagement/revenueManagement/filesDia.vue @@ -0,0 +1,202 @@ +<template> + <div> + <el-dialog + v-model="dialogFormVisible" + title="涓婁紶闄勪欢" + width="50%" + @close="closeDia" + > + <div style="margin-bottom: 10px;text-align: right"> + <el-upload + v-model:file-list="fileList" + class="upload-demo" + :action="uploadUrl" + :on-success="handleUploadSuccess" + :on-error="handleUploadError" + name="file" + :show-file-list="false" + :headers="headers" + style="display: inline;margin-right: 10px" + > + <el-button type="primary">涓婁紶闄勪欢</el-button> + </el-upload> + <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button> + </div> + <PIMTable + rowKey="id" + :column="tableColumn" + :tableData="tableData" + :tableLoading="tableLoading" + :isSelection="true" + @selection-change="handleSelectionChange" + height="500" + > + </PIMTable> + <pagination + style="margin: 10px 0" + v-show="total > 0" + @pagination="paginationSearch" + :total="total" + :page="page.current" + :limit="page.size" + /> + <template #footer> + <div class="dialog-footer"> + <el-button @click="closeDia">鍙栨秷</el-button> + </div> + </template> + </el-dialog> + <filePreview ref="filePreviewRef" /> + </div> +</template> + +<script setup> +import {ref} from "vue"; +import {ElMessageBox} from "element-plus"; +import {getToken} from "@/utils/auth.js"; +import filePreview from '@/components/filePreview/index.vue' +import { + fileAdd, + fileDel, + fileListPage +} from "@/api/financialManagement/revenueManagement.js"; +import Pagination from "@/components/PIMTable/Pagination.vue"; +const { proxy } = getCurrentInstance() +const emit = defineEmits(['close']) + +const dialogFormVisible = ref(false); +const currentId = ref('') +const selectedRows = ref([]); +const filePreviewRef = ref() +const tableColumn = ref([ + { + label: "鏂囦欢鍚嶇О", + prop: "name", + }, + { + dataType: "action", + label: "鎿嶄綔", + align: "center", + operation: [ + { + name: "涓嬭浇", + type: "text", + clickFun: (row) => { + downLoadFile(row); + }, + }, + { + name: "棰勮", + type: "text", + clickFun: (row) => { + lookFile(row); + }, + } + ], + }, +]); +const page = reactive({ + current: 1, + size: 100, +}); +const total = ref(0); +const tableData = ref([]); +const fileList = ref([]); +const tableLoading = ref(false); +const accountType = ref('') +const headers = ref({ + Authorization: "Bearer " + getToken(), +}); +const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃 + +// 鎵撳紑寮规 +const openDialog = (row,type) => { + accountType.value = type; + dialogFormVisible.value = true; + currentId.value = row.id; + getList() +} +const paginationSearch = (obj) => { + page.current = obj.page; + page.size = obj.limit; + getList(); +}; +const getList = () => { + fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => { + tableData.value = res.data.records; + total.value = res.data.total; + }) +} +// 琛ㄦ牸閫夋嫨鏁版嵁 +const handleSelectionChange = (selection) => { + selectedRows.value = selection; +}; + +// 鍏抽棴寮规 +const closeDia = () => { + dialogFormVisible.value = false; + emit('close') +}; +// 涓婁紶鎴愬姛澶勭悊 +function handleUploadSuccess(res, file) { + // 濡傛灉涓婁紶鎴愬姛 + if (res.code == 200) { + const fileRow = {} + fileRow.name = res.data.originalName + fileRow.url = res.data.tempPath + uploadFile(fileRow) + } else { + proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触"); + } +} +function uploadFile(file) { + file.accountId = currentId.value; + file.accountType = accountType.value; + fileAdd(file).then(res => { + proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛"); + getList() + }) +} +// 涓婁紶澶辫触澶勭悊 +function handleUploadError() { + proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触"); +} +// 涓嬭浇闄勪欢 +const downLoadFile = (row) => { + proxy.$download.name(row.url); +} +// 鍒犻櫎 +const handleDelete = () => { + let ids = []; + if (selectedRows.value.length > 0) { + ids = selectedRows.value.map((item) => item.id); + } else { + proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁"); + return; + } + ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", { + confirmButtonText: "纭", + cancelButtonText: "鍙栨秷", + type: "warning", + }).then(() => { + fileDel(ids).then((res) => { + proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + getList(); + }); + }).catch(() => { + proxy.$modal.msg("宸插彇娑�"); + }); +}; +// 棰勮闄勪欢 +const lookFile = (row) => { + filePreviewRef.value.open(row.url) +} + +defineExpose({ + openDialog, +}); +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/financialManagement/revenueManagement/index.vue b/src/views/financialManagement/revenueManagement/index.vue new file mode 100644 index 0000000..984d9de --- /dev/null +++ b/src/views/financialManagement/revenueManagement/index.vue @@ -0,0 +1,279 @@ +<template> + <div class="app-container"> + <el-form :model="filters" :inline="true"> + <el-form-item label="褰曞叆鏃ユ湡:"> + <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" + placeholder="璇烽�夋嫨" clearable @change="changeDaterange" /> + </el-form-item> + <el-form-item label="鏀舵鏂瑰紡:"> + <el-select + v-model="filters.incomeMethod" + placeholder="璇烽�夋嫨" + clearable + style="width: 200px;" + > + <el-option + v-for="item in payment_methods" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="getTableData">鎼滅储</el-button> + <el-button @click="resetFilters">閲嶇疆</el-button> + </el-form-item> + </el-form> + <div class="table_list"> + <div class="actions"> + <div></div> + <div> + <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button> + <el-button @click="handleOut" icon="download">瀵煎嚭</el-button> + <el-button + type="danger" + icon="Delete" + :disabled="multipleList.length <= 0" + @click="deleteRow(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" + @pagination="changePage" + > + <template #operation="{ row }"> + <el-button type="primary" text @click="edit(row.id)" icon="editPen"> + 缂栬緫 + </el-button> + <el-button + type="primary" + text + @click="openFilesFormDia(row)" + > + 闄勪欢 + </el-button> + </template> + </PIMTable> + </div> + <Modal ref="modalRef" @success="getTableData"></Modal> + <files-dia ref="filesDia" @close="handleQuery"></files-dia> + </div> +</template> + +<script setup> +import { usePaginationApi } from "@/hooks/usePaginationApi"; +import { listPage, delAccountIncome } from "@/api/financialManagement/revenueManagement"; +import { onMounted, getCurrentInstance } from "vue"; +import Modal from "./Modal.vue"; +import { ElMessageBox, ElMessage } from "element-plus"; +import dayjs from "dayjs"; +import FilesDia from "./filesDia.vue"; + +defineOptions({ + name: "鏀跺叆绠$悊", +}); + +// 琛ㄦ牸澶氶�夋閫変腑椤� +const multipleList = ref([]); +const { proxy } = getCurrentInstance(); +const modalRef = ref(); +const { payment_methods } = proxy.useDict("payment_methods"); +const { income_types } = proxy.useDict("income_types"); +const filesDia = ref() + +const { + filters, + columns, + dataList, + pagination, + getTableData, + resetFilters, + onCurrentChange, +} = usePaginationApi( + listPage, + { + incomeMethod: undefined, + }, + [ + { + label: "鏀跺叆鏃ユ湡", + align: "center", + prop: "incomeDate", + }, + { + label: "鏀跺叆绫诲瀷", + align: "center", + prop: "incomeType", + dataType: "tag", + formatData: (params) => { + if (income_types.value.find((m) => m.value == params)) { + return income_types.value.find((m) => m.value == params).label; + } else { + return null + } + }, + }, + { + label: "瀹㈡埛鍚嶇О", + align: "center", + prop: "customerName", + + }, + { + label: "鏀跺叆閲戦", + align: "center", + prop: "incomeMoney", + + }, + { + label: "鏀跺叆鎻忚堪", + align: "center", + prop: "incomeDescribed", + + }, + { + label: "鏀舵鏂瑰紡", + align: "center", + prop: "incomeMethod", + dataType: "tag", + formatData: (params) => { + if (payment_methods.value.find((m) => m.value == params)) { + return payment_methods.value.find((m) => m.value == params).label; + } else { + return null + } + }, + }, + { + label: "鍙戠エ鍙风爜", + align: "center", + prop: "invoiceNumber", + + }, + { + label: "澶囨敞", + align: "center", + prop: "note", + + }, + { + label: "褰曞叆浜�", + align: "center", + prop: "inputUser", + }, + { + label: "褰曞叆鏃ユ湡", + align: "center", + prop: "inputTime", + + }, + { + fixed: "right", + label: "鎿嶄綔", + dataType: "slot", + slot: "operation", + align: "center", + width: "200px", + }, + ] +); + +// 澶氶�夊悗鍋氫粈涔� +const handleSelectionChange = (selectionList) => { + multipleList.value = selectionList; +}; + +const add = () => { + modalRef.value.openModal(); +}; +const edit = (id) => { + modalRef.value.loadForm(id); +}; +const changePage = ({ page, limit }) => { + pagination.currentPage = page; + pagination.pageSize = limit; + onCurrentChange(page); +}; +const deleteRow = (id) => { + ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning", + }).then(async () => { + const { code } = await delAccountIncome(id); + if (code == 200) { + ElMessage({ + type: "success", + message: "鍒犻櫎鎴愬姛", + }); + getTableData(); + } + }); +}; + +const changeDaterange = (value) => { + if (value) { + filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); + filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); + } else { + filters.entryDateStart = undefined; + filters.entryDateEnd = undefined; + } + getTableData(); +}; + +const handleOut = () => { + ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", { + confirmButtonText: "纭", + cancelButtonText: "鍙栨秷", + type: "warning", + }) + .then(() => { + proxy.download(`/account/accountIncome/export`, {}, "鏀跺叆鍙拌处.xlsx"); + }) + .catch(() => { + proxy.$modal.msg("宸插彇娑�"); + }); +}; +// 鎵撳紑闄勪欢寮规 +const openFilesFormDia = (row) => { + nextTick(() => { + filesDia.value?.openDialog( row,'鏀跺叆') + }) +}; + +onMounted(() => { + filters.entryDate = [ + dayjs().format("YYYY-MM-DD"), + dayjs().add(1, "day").format("YYYY-MM-DD"), + ] + filters.entryDateStart = dayjs().format("YYYY-MM-DD") + filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD") + getTableData(); +}); +</script> + +<style lang="scss" scoped> +.table_list { + margin-top: unset; +} +.actions { + display: flex; + justify-content: space-between; + margin-bottom: 10px; +} +</style> + diff --git a/src/views/salesManagement/salesLedger/fileList.vue b/src/views/salesManagement/salesLedger/fileList.vue index d1c0cdd..da37db2 100644 --- a/src/views/salesManagement/salesLedger/fileList.vue +++ b/src/views/salesManagement/salesLedger/fileList.vue @@ -1,22 +1,26 @@ <template> - <el-dialog v-model="dialogVisible" title="闄勪欢" width="30%" :before-close="handleClose"> + <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose"> <el-table :data="tableData" border height="40vh"> <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip /> <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center"> <template #default="scope"> <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button> + <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button> </template> </el-table-column> </el-table> </el-dialog> + <filePreview ref="filePreviewRef" /> </template> <script setup> import { ref } from 'vue' +import filePreview from '@/components/filePreview/index.vue' const dialogVisible = ref(false) const tableData = ref([]) const { proxy } = getCurrentInstance(); +const filePreviewRef = ref() const handleClose = () => { dialogVisible.value = false } @@ -28,6 +32,9 @@ proxy.$download.name(row.url); } +const lookFile = (row) => { + filePreviewRef.value.open(row.url) +} defineExpose({ open }) -- Gitblit v1.9.3