Commit 07c554d7c7dbb308012e604948118eb153ab93cd

Authored by 李宇
1 parent 42273b70

报销

antis-ncc-admin/.env.development
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 VUE_CLI_BABEL_TRANSPILE_MODULES = true 3 VUE_CLI_BABEL_TRANSPILE_MODULES = true
4 # VUE_APP_BASE_API = 'https://erp.lvqianmeiye.com' 4 # VUE_APP_BASE_API = 'https://erp.lvqianmeiye.com'
5 -# VUE_APP_BASE_API = 'http://erp_test.lvqianmeiye.com'  
6 -VUE_APP_BASE_API = 'http://localhost:2011' 5 +VUE_APP_BASE_API = 'http://erp_test.lvqianmeiye.com'
  6 +# VUE_APP_BASE_API = 'http://localhost:2011'
7 # VUE_APP_BASE_API = 'http://localhost:2011' 7 # VUE_APP_BASE_API = 'http://localhost:2011'
8 VUE_APP_BASE_WSS = 'ws://192.168.110.45:2011/websocket' 8 VUE_APP_BASE_WSS = 'ws://192.168.110.45:2011/websocket'
antis-ncc-admin/src/views/lqReimbursementApplication/ExportBox.vue renamed to antis-ncc-admin/src/views/lqReimbursementApplication copy/ExportBox.vue
antis-ncc-admin/src/views/lqReimbursementApplication/Form.vue renamed to antis-ncc-admin/src/views/lqReimbursementApplication copy/Form.vue
antis-ncc-admin/src/views/lqReimbursementApplication/detail.vue renamed to antis-ncc-admin/src/views/lqReimbursementApplication copy/detail.vue
antis-ncc-admin/src/views/lqReimbursementApplication copy/index.vue 0 → 100644
  1 +<template>
  2 + <div class="NCC-common-layout">
  3 + <div class="NCC-common-layout-center">
  4 + <el-row class="NCC-common-search-box" :gutter="16">
  5 + <el-form @submit.native.prevent>
  6 +
  7 + <el-col :span="6">
  8 + <el-form-item label="申请时间">
  9 + <el-date-picker v-model="query.applicationTime" type="daterange" value-format="timestamp" format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期">
  10 + </el-date-picker>
  11 + </el-form-item>
  12 + </el-col>
  13 + <el-col :span="6">
  14 + <el-form-item label="申请人">
  15 + <userSelect v-model="query.applicationUserId" placeholder="请选择申请人" clearable />
  16 + </el-form-item>
  17 + </el-col>
  18 + <el-col :span="6">
  19 + <el-form-item label="门店">
  20 + <el-select v-model="query.applicationStoreId" placeholder="请选择门店" clearable filterable style="width: 100%">
  21 + <el-option
  22 + v-for="store in storeOptions"
  23 + :key="store.id"
  24 + :label="store.dm"
  25 + :value="store.id">
  26 + </el-option>
  27 + </el-select>
  28 + </el-form-item>
  29 + </el-col>
  30 + <template v-if="showAll">
  31 + <el-col :span="6">
  32 + <el-form-item label="审批状态">
  33 + <el-select v-model="query.approveStatus" placeholder="请选择审批状态" clearable style="width: 100%">
  34 + <el-option label="已审批" value="已审批"></el-option>
  35 + <el-option label="未通过" value="未通过"></el-option>
  36 + <el-option label="未审批" value="未审批"></el-option>
  37 + </el-select>
  38 + </el-form-item>
  39 + </el-col>
  40 + <!-- <el-col :span="6">
  41 + <el-form-item label="审批时间">
  42 + <el-date-picker v-model="query.approveTime" type="daterange" value-format="timestamp" format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期">
  43 + </el-date-picker>
  44 + </el-form-item>
  45 + </el-col> -->
  46 +
  47 + <!-- <el-col :span="6">
  48 + <el-form-item label="总金额">
  49 + <el-input v-model="query.amount" placeholder="总金额" clearable />
  50 + </el-form-item>
  51 + </el-col> -->
  52 + <!-- <el-col :span="6">
  53 + <el-form-item label="审批人">
  54 + <userSelect v-model="query.approveUser" placeholder="请选择审批人" />
  55 + </el-form-item>
  56 + </el-col>
  57 + <el-col :span="6">
  58 + <el-form-item label="审批结果">
  59 + <el-input v-model="query.approveStatus" placeholder="审批结果" clearable />
  60 + </el-form-item>
  61 + </el-col> -->
  62 + <!-- <el-col :span="6">
  63 + <el-form-item label="关联购买编号">
  64 + <el-input v-model="query.purchaseRecordsId" placeholder="关联购买编号" clearable />
  65 + </el-form-item>
  66 + </el-col> -->
  67 + </template>
  68 + <el-col :span="6">
  69 + <el-form-item>
  70 + <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
  71 + <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button>
  72 + <el-button type="text" icon="el-icon-arrow-down" @click="showAll=true" v-if="!showAll">展开</el-button>
  73 + <el-button type="text" icon="el-icon-arrow-up" @click="showAll=false" v-else>收起</el-button>
  74 + </el-form-item>
  75 + </el-col>
  76 + </el-form>
  77 + </el-row>
  78 + <div class="NCC-common-layout-main NCC-flex-main">
  79 + <div class="NCC-common-head">
  80 + <div>
  81 + <el-button type="primary" icon="el-icon-plus" @click="addOrUpdateHandle()">新增</el-button>
  82 + <el-button type="text" icon="el-icon-delete" @click="handleBatchRemoveDel()">批量删除</el-button>
  83 + <!-- <el-button type="text" icon="el-icon-download" @click="exportData()">导出</el-button>
  84 + <el-button type="text" icon="el-icon-delete" @click="handleBatchRemoveDel()">批量删除</el-button> -->
  85 + </div>
  86 + <div class="NCC-common-head-right">
  87 + <el-tooltip effect="dark" content="刷新" placement="top">
  88 + <el-link icon="icon-ym icon-ym-Refresh NCC-common-head-icon" :underline="false" @click="reset()" />
  89 + </el-tooltip>
  90 + <screenfull isContainer />
  91 + </div>
  92 + </div>
  93 + <NCC-table v-loading="listLoading" :data="list" has-c @selection-change="handleSelectionChange">
  94 + <!-- <el-table-column prop="id" label="申请编号" align="left" /> -->
  95 + <!-- <el-table-column prop="applicationUserId" label="申请人编号" align="left" /> -->
  96 + <el-table-column prop="applicationUserName" label="申请人" align="left" />
  97 + <el-table-column prop="applicationStoreId" label="门店" align="left">
  98 + <template slot-scope="scope">
  99 + <div class="store-info">
  100 + <i class="el-icon-shop"></i>
  101 + <span>{{ getStoreName(scope.row.applicationStoreId) || '无' }}</span>
  102 + </div>
  103 + </template>
  104 + </el-table-column>
  105 + <el-table-column prop="applicationTime" label="申请时间" align="left" :formatter="ncc.tableDateFormat" />
  106 + <el-table-column prop="amount" label="总金额" align="left" />
  107 + <el-table-column prop="approveStatus" label="审批状态" align="left"/>
  108 + <el-table-column prop="approveTime" label="审批时间" align="left" :formatter="ncc.tableDateFormat" />
  109 + <!-- <el-table-column prop="approveUser" label="审批人" align="left" />
  110 + <el-table-column prop="approveStatus" label="审批结果" align="left" /> -->
  111 + <!-- <el-table-column prop="purchaseRecordsId" label="关联购买编号" align="left" /> -->
  112 + <el-table-column label="操作" fixed="right" width="100">
  113 + <template slot-scope="scope">
  114 + <el-button type="text" v-if="scope.row.approveStatus === '未审批'" @click="addOrUpdateHandle(scope.row.id)" >编辑</el-button>
  115 + <el-button type="text" v-if="scope.row.approveStatus === '已审批'" @click="showDetail(scope.row.id)" >查看</el-button>
  116 + <!-- <el-button type="text" v-if="scope.row.approveStatus === '未审批'" @click="handleDel(scope.row.id)" class="NCC-table-delBtn" >删除</el-button> -->
  117 + </template>
  118 + </el-table-column>
  119 + </NCC-table>
  120 + <pagination :total="total" :page.sync="listQuery.currentPage" :limit.sync="listQuery.pageSize" @pagination="initData" />
  121 + </div>
  122 + </div>
  123 + <NCC-Form v-if="formVisible" ref="NCCForm" @refresh="refresh" />
  124 + <ExportBox v-if="exportBoxVisible" ref="ExportBox" @download="download" />
  125 + <DetailDialog v-if="detailVisible" ref="DetailDialog" @close="handleDetailClose" />
  126 + </div>
  127 +</template>
  128 +<script>
  129 + import request from '@/utils/request'
  130 + import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
  131 + import { getStoreSelector } from '@/api/extend/store'
  132 + import NCCForm from './Form'
  133 + import ExportBox from './ExportBox'
  134 + import DetailDialog from './detail'
  135 + import { previewDataInterface } from '@/api/systemData/dataInterface'
  136 + export default {
  137 + components: { NCCForm, ExportBox, DetailDialog },
  138 + data() {
  139 + return {
  140 + showAll: false,
  141 + storeOptions: [],
  142 + storeMap: {},
  143 + detailVisible: false,
  144 + query: {
  145 + id:undefined,
  146 + applicationUserId:undefined,
  147 + applicationUserName:undefined,
  148 + applicationStoreId:undefined,
  149 + applicationTime:undefined,
  150 + amount:undefined,
  151 + approveUser:undefined,
  152 + approveStatus:undefined,
  153 + approveTime:undefined,
  154 + purchaseRecordsId:undefined,
  155 + },
  156 + list: [],
  157 + listLoading: true,
  158 + multipleSelection: [], total: 0,
  159 + listQuery: {
  160 + currentPage: 1,
  161 + pageSize: 20,
  162 + sort: "desc",
  163 + sidx: "",
  164 + },
  165 + formVisible: false,
  166 + exportBoxVisible: false,
  167 + columnList: [
  168 + { prop: 'id', label: '申请编号' },
  169 + { prop: 'applicationUserId', label: '申请人编号' },
  170 + { prop: 'applicationUserName', label: '申请人姓名' },
  171 + { prop: 'applicationStoreId', label: '申请门店' },
  172 + { prop: 'applicationTime', label: '申请时间' },
  173 + { prop: 'amount', label: '总金额' },
  174 + { prop: 'approveUser', label: '审批人' },
  175 + { prop: 'approveStatus', label: '审批结果' },
  176 + { prop: 'approveTime', label: '审批时间' },
  177 + { prop: 'purchaseRecordsId', label: '关联购买编号' },
  178 + ],
  179 + }
  180 + },
  181 + computed: {},
  182 + created() {
  183 + this.loadStoreOptions()
  184 + this.initData()
  185 + },
  186 + methods: {
  187 + // 加载门店列表
  188 + loadStoreOptions() {
  189 + request({
  190 + url: '/api/Extend/LqMdxx',
  191 + method: 'GET',
  192 + data: {
  193 + currentPage: 1,
  194 + pageSize: 1000
  195 + }
  196 + }).then(res => {
  197 + if (res.data && res.data.list) {
  198 + this.storeOptions = res.data.list;
  199 + }
  200 + }).catch(() => {
  201 + this.storeOptions = [];
  202 + });
  203 + },
  204 +
  205 + getStoreName(storeId) {
  206 + if (!storeId) return '无';
  207 + const store = this.storeOptions.find(item => item.id === storeId);
  208 + return store ? store.dm : '无';
  209 + },
  210 + initData() {
  211 + this.listLoading = true;
  212 + let _query = {
  213 + ...this.listQuery,
  214 + ...this.query
  215 + };
  216 + let query = {}
  217 + for (let key in _query) {
  218 + if (Array.isArray(_query[key])) {
  219 + query[key] = _query[key].join()
  220 + } else {
  221 + query[key] = _query[key]
  222 + }
  223 + }
  224 + request({
  225 + url: `/api/Extend/LqReimbursementApplication`,
  226 + method: 'GET',
  227 + data: query
  228 + }).then(res => {
  229 + this.list = res.data.list
  230 + this.total = res.data.pagination.total
  231 + this.listLoading = false
  232 + })
  233 + },
  234 + handleDel(id) {
  235 + this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  236 + type: 'warning'
  237 + }).then(() => {
  238 + request({
  239 + url: `/api/Extend/LqReimbursementApplication/${id}`,
  240 + method: 'DELETE'
  241 + }).then(res => {
  242 + this.$message({
  243 + type: 'success',
  244 + message: res.msg,
  245 + onClose: () => {
  246 + this.initData()
  247 + }
  248 + });
  249 + })
  250 + }).catch(() => {
  251 + });
  252 + },
  253 + handleSelectionChange(val) {
  254 + const res = val.map(item => item.id)
  255 + this.multipleSelection = res
  256 + },
  257 + handleBatchRemoveDel() {
  258 + if (!this.multipleSelection.length) {
  259 + this.$message({
  260 + type: 'error',
  261 + message: '请选择一条数据',
  262 + duration: 1500,
  263 + })
  264 + return
  265 + }
  266 + const ids = this.multipleSelection
  267 + this.$confirm('您确定要删除这些数据吗, 是否继续?', '提示', {
  268 + type: 'warning'
  269 + }).then(() => {
  270 + request({
  271 + url: `/api/Extend/LqReimbursementApplication/batchRemove`,
  272 + method: 'POST',
  273 + data: ids ,
  274 + }).then(res => {
  275 + this.$message({
  276 + type: 'success',
  277 + message: res.msg,
  278 + onClose: () => {
  279 + this.initData()
  280 + }
  281 + });
  282 + })
  283 + }).catch(() => { })
  284 + },
  285 + addOrUpdateHandle(id, isDetail) {
  286 + this.formVisible = true
  287 + this.$nextTick(() => {
  288 + this.$refs.NCCForm.init(id, isDetail)
  289 + })
  290 + },
  291 + exportData() {
  292 + this.exportBoxVisible = true
  293 + this.$nextTick(() => {
  294 + this.$refs.ExportBox.init(this.columnList)
  295 + })
  296 + },
  297 + download(data) {
  298 + let query = { ...data, ...this.listQuery, ...this.query }
  299 + request({
  300 + url: `/api/Extend/LqReimbursementApplication/Actions/Export`,
  301 + method: 'GET',
  302 + data: query
  303 + }).then(res => {
  304 + if (!res.data.url) return
  305 + window.location.href = this.define.comUrl + res.data.url
  306 + this.$refs.ExportBox.visible = false
  307 + this.exportBoxVisible = false
  308 + })
  309 + },
  310 + search() {
  311 + this.listQuery = {
  312 + currentPage: 1,
  313 + pageSize: 20,
  314 + sort: "desc",
  315 + sidx: "",
  316 + }
  317 + this.initData()
  318 + },
  319 + refresh(isrRefresh) {
  320 + this.formVisible = false
  321 + if (isrRefresh) this.reset()
  322 + },
  323 + reset() {
  324 + for (let key in this.query) {
  325 + this.query[key] = undefined
  326 + }
  327 + this.listQuery = {
  328 + currentPage: 1,
  329 + pageSize: 20,
  330 + sort: "desc",
  331 + sidx: "",
  332 + }
  333 + this.initData()
  334 + },
  335 + showDetail(id) {
  336 + this.detailVisible = true
  337 + this.$nextTick(() => {
  338 + this.$refs.DetailDialog.init(id)
  339 + })
  340 + },
  341 + handleDetailClose() {
  342 + this.detailVisible = false
  343 + }
  344 + }
  345 + }
  346 +</script>
  347 +<style lang="scss" scoped>
  348 +.store-info {
  349 + display: flex;
  350 + align-items: center;
  351 + gap: 6px;
  352 +
  353 + i {
  354 + color: #67C23A;
  355 + font-size: 14px;
  356 + }
  357 +
  358 + span {
  359 + color: #303133;
  360 + }
  361 +}
  362 +</style>
0 \ No newline at end of file 363 \ No newline at end of file
antis-ncc-admin/src/views/lqReimbursementApplication/approval-history-dialog.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + title="审批历史"
  4 + :visible.sync="visible"
  5 + :close-on-click-modal="false"
  6 + class="NCC-dialog NCC-dialog_center"
  7 + width="900px"
  8 + @close="handleClose"
  9 + >
  10 + <div class="history-content" v-loading="loading">
  11 + <el-timeline v-if="historyList && historyList.length > 0">
  12 + <el-timeline-item
  13 + v-for="(item, index) in historyList"
  14 + :key="index"
  15 + :timestamp="formatDateTime(item.approvalTime)"
  16 + placement="top"
  17 + :type="getTimelineType(item.approvalResult)"
  18 + :icon="getTimelineIcon(item.approvalResult)"
  19 + >
  20 + <el-card class="history-card">
  21 + <div class="history-header">
  22 + <div class="history-node-info">
  23 + <span class="node-name">{{ item.nodeName || '无' }}</span>
  24 + <el-tag size="small" type="info">第{{ item.nodeOrder }}节点</el-tag>
  25 + </div>
  26 + <el-tag
  27 + :type="getRecordType(item.approvalResult)"
  28 + size="medium"
  29 + >
  30 + {{ item.approvalResult || '无' }}
  31 + </el-tag>
  32 + </div>
  33 + <div class="history-body">
  34 + <div class="history-item">
  35 + <span class="history-label">审批人:</span>
  36 + <span class="history-value">{{ item.approverName || '无' }}</span>
  37 + </div>
  38 + <div class="history-item" v-if="item.approvalOpinion">
  39 + <span class="history-label">审批意见:</span>
  40 + <span class="history-value">{{ item.approvalOpinion }}</span>
  41 + </div>
  42 + <div class="history-item" v-if="item.approvalTime">
  43 + <span class="history-label">审批时间:</span>
  44 + <span class="history-value">{{ formatDateTime(item.approvalTime) }}</span>
  45 + </div>
  46 + </div>
  47 + </el-card>
  48 + </el-timeline-item>
  49 + </el-timeline>
  50 + <el-empty v-else description="暂无审批历史" :image-size="120" />
  51 + </div>
  52 + <span slot="footer" class="dialog-footer">
  53 + <el-button @click="visible = false">关 闭</el-button>
  54 + </span>
  55 + </el-dialog>
  56 +</template>
  57 +
  58 +<script>
  59 +import request from '@/utils/request'
  60 +
  61 +export default {
  62 + name: 'ApprovalHistoryDialog',
  63 + data() {
  64 + return {
  65 + visible: false,
  66 + loading: false,
  67 + historyList: []
  68 + }
  69 + },
  70 + methods: {
  71 + init(id) {
  72 + this.visible = true
  73 + this.loading = true
  74 + this.historyList = []
  75 + this.getHistory(id)
  76 + },
  77 +
  78 + async getHistory(id) {
  79 + try {
  80 + const response = await request({
  81 + url: `/api/Extend/LqReimbursementApplication/${id}/Actions/ApprovalHistory`,
  82 + method: 'GET'
  83 + })
  84 +
  85 + if (response.code === 200) {
  86 + this.historyList = response.data || []
  87 + } else {
  88 + this.$message.error(response.msg || '获取审批历史失败')
  89 + this.historyList = []
  90 + }
  91 + } catch (error) {
  92 + console.error('获取审批历史失败:', error)
  93 + this.$message.error('获取审批历史失败')
  94 + this.historyList = []
  95 + } finally {
  96 + this.loading = false
  97 + }
  98 + },
  99 +
  100 + handleClose() {
  101 + this.visible = false
  102 + this.historyList = []
  103 + },
  104 +
  105 + formatDateTime(dateTime) {
  106 + if (!dateTime) return '无'
  107 + // 如果是时间戳(数字),需要转换
  108 + if (typeof dateTime === 'number') {
  109 + const date = new Date(dateTime)
  110 + const year = date.getFullYear()
  111 + const month = String(date.getMonth() + 1).padStart(2, '0')
  112 + const day = String(date.getDate()).padStart(2, '0')
  113 + const hours = String(date.getHours()).padStart(2, '0')
  114 + const minutes = String(date.getMinutes()).padStart(2, '0')
  115 + const seconds = String(date.getSeconds()).padStart(2, '0')
  116 + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  117 + }
  118 + // 如果是字符串,直接返回
  119 + const date = new Date(dateTime)
  120 + if (isNaN(date.getTime())) return dateTime
  121 + const year = date.getFullYear()
  122 + const month = String(date.getMonth() + 1).padStart(2, '0')
  123 + const day = String(date.getDate()).padStart(2, '0')
  124 + const hours = String(date.getHours()).padStart(2, '0')
  125 + const minutes = String(date.getMinutes()).padStart(2, '0')
  126 + const seconds = String(date.getSeconds()).padStart(2, '0')
  127 + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  128 + },
  129 +
  130 + getRecordType(result) {
  131 + const typeMap = {
  132 + '待审批': 'info',
  133 + '通过': 'success',
  134 + '不通过': 'danger',
  135 + '退回': 'warning'
  136 + }
  137 + return typeMap[result] || ''
  138 + },
  139 +
  140 + getTimelineType(result) {
  141 + const typeMap = {
  142 + '待审批': '',
  143 + '通过': 'success',
  144 + '不通过': 'danger',
  145 + '退回': 'warning'
  146 + }
  147 + return typeMap[result] || ''
  148 + },
  149 +
  150 + getTimelineIcon(result) {
  151 + const iconMap = {
  152 + '待审批': 'el-icon-time',
  153 + '通过': 'el-icon-check',
  154 + '不通过': 'el-icon-close',
  155 + '退回': 'el-icon-back'
  156 + }
  157 + return iconMap[result] || 'el-icon-time'
  158 + }
  159 + }
  160 +}
  161 +</script>
  162 +
  163 +<style lang="scss" scoped>
  164 +.history-content {
  165 + max-height: 70vh;
  166 + overflow-y: auto;
  167 + padding: 20px 0;
  168 +}
  169 +
  170 +.history-card {
  171 + margin-bottom: 8px;
  172 +
  173 + .history-header {
  174 + display: flex;
  175 + justify-content: space-between;
  176 + align-items: center;
  177 + margin-bottom: 12px;
  178 +
  179 + .history-node-info {
  180 + display: flex;
  181 + align-items: center;
  182 + gap: 8px;
  183 +
  184 + .node-name {
  185 + font-weight: 600;
  186 + color: #303133;
  187 + font-size: 16px;
  188 + }
  189 + }
  190 + }
  191 +
  192 + .history-body {
  193 + .history-item {
  194 + margin-bottom: 8px;
  195 + display: flex;
  196 + align-items: flex-start;
  197 +
  198 + &:last-child {
  199 + margin-bottom: 0;
  200 + }
  201 +
  202 + .history-label {
  203 + min-width: 80px;
  204 + color: #606266;
  205 + font-weight: 500;
  206 + }
  207 +
  208 + .history-value {
  209 + color: #303133;
  210 + flex: 1;
  211 + word-break: break-all;
  212 + }
  213 + }
  214 + }
  215 +}
  216 +</style>
  217 +
antis-ncc-admin/src/views/lqReimbursementApplication/detail-dialog.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + title="报销申请详情"
  4 + :visible.sync="visible"
  5 + :close-on-click-modal="false"
  6 + class="NCC-dialog NCC-dialog_center"
  7 + width="1200px"
  8 + @close="handleClose"
  9 + >
  10 + <div class="detail-content" v-loading="loading">
  11 + <!-- 表单信息卡片 -->
  12 + <el-card class="info-card" shadow="hover" v-if="formData">
  13 + <div slot="header" class="card-header">
  14 + <i class="el-icon-document"></i>
  15 + <span class="card-title">申请信息</span>
  16 + </div>
  17 + <el-row :gutter="20">
  18 + <el-col :span="8">
  19 + <div class="info-item">
  20 + <label class="info-label">申请编号:</label>
  21 + <span class="info-value">{{ formData.id || '无' }}</span>
  22 + </div>
  23 + </el-col>
  24 + <el-col :span="8">
  25 + <div class="info-item">
  26 + <label class="info-label">申请人编号:</label>
  27 + <span class="info-value">{{ formData.applicationUserId || '无' }}</span>
  28 + </div>
  29 + </el-col>
  30 + <el-col :span="8">
  31 + <div class="info-item">
  32 + <label class="info-label">申请人姓名:</label>
  33 + <span class="info-value">{{ formData.applicationUserName || '无' }}</span>
  34 + </div>
  35 + </el-col>
  36 + <el-col :span="8">
  37 + <div class="info-item">
  38 + <label class="info-label">申请门店ID:</label>
  39 + <span class="info-value">{{ formData.applicationStoreId || '无' }}</span>
  40 + </div>
  41 + </el-col>
  42 + <el-col :span="8">
  43 + <div class="info-item">
  44 + <label class="info-label">申请时间:</label>
  45 + <span class="info-value">{{ formatDateTime(formData.applicationTime) || '无' }}</span>
  46 + </div>
  47 + </el-col>
  48 + <el-col :span="8">
  49 + <div class="info-item">
  50 + <label class="info-label">总金额:</label>
  51 + <span class="info-value amount">{{ formatMoney(formData.amount) || '无' }}</span>
  52 + </div>
  53 + </el-col>
  54 + <el-col :span="8">
  55 + <div class="info-item">
  56 + <label class="info-label">审批状态:</label>
  57 + <el-tag
  58 + :type="getStatusType(formData.approveStatus)"
  59 + size="small"
  60 + >
  61 + {{ formData.approveStatus || '无' }}
  62 + </el-tag>
  63 + </div>
  64 + </el-col>
  65 + <el-col :span="8">
  66 + <div class="info-item">
  67 + <label class="info-label">购买记录编号:</label>
  68 + <span class="info-value">{{ formData.purchaseRecordsId || '无' }}</span>
  69 + </div>
  70 + </el-col>
  71 + </el-row>
  72 + </el-card>
  73 +
  74 + <!-- 审批流程卡片 -->
  75 + <el-card class="info-card" shadow="hover" v-if="nodes && nodes.length > 0">
  76 + <div slot="header" class="card-header">
  77 + <i class="el-icon-s-order"></i>
  78 + <span class="card-title">审批流程</span>
  79 + </div>
  80 + <div class="approval-flow">
  81 + <div
  82 + v-for="(node, index) in nodes"
  83 + :key="node.nodeId"
  84 + class="flow-node"
  85 + :class="{
  86 + 'node-active': node.nodeOrder === currentNodeOrder,
  87 + 'node-completed': node.nodeOrder < currentNodeOrder,
  88 + 'node-pending': node.nodeOrder > currentNodeOrder
  89 + }"
  90 + >
  91 + <div class="node-header">
  92 + <div class="node-order">{{ node.nodeOrder }}</div>
  93 + <div class="node-info">
  94 + <div class="node-name">{{ node.nodeName || '无' }}</div>
  95 + <div class="node-type">
  96 + <el-tag size="mini" :type="node.approvalType === '会签' ? 'success' : 'warning'">
  97 + {{ node.approvalType || '无' }}
  98 + </el-tag>
  99 + <el-tag size="mini" type="info" v-if="node.isRequired === 1">必审</el-tag>
  100 + </div>
  101 + </div>
  102 + </div>
  103 +
  104 + <!-- 审批人列表 -->
  105 + <div class="approvers-list">
  106 + <div class="approvers-label">审批人:</div>
  107 + <div class="approvers-items">
  108 + <el-tag
  109 + v-for="approver in node.approvers"
  110 + :key="approver.userId"
  111 + size="small"
  112 + style="margin-right: 8px; margin-bottom: 4px;"
  113 + >
  114 + {{ approver.userName || '无' }}
  115 + </el-tag>
  116 + </div>
  117 + </div>
  118 +
  119 + <!-- 审批记录 -->
  120 + <div class="approval-records" v-if="node.approvalRecords && node.approvalRecords.length > 0">
  121 + <div class="records-label">审批记录:</div>
  122 + <div class="records-list">
  123 + <div
  124 + v-for="(record, recordIndex) in node.approvalRecords"
  125 + :key="recordIndex"
  126 + class="record-item"
  127 + >
  128 + <div class="record-header">
  129 + <span class="record-approver">{{ record.approverName || '无' }}</span>
  130 + <el-tag
  131 + size="mini"
  132 + :type="getRecordType(record.approvalResult)"
  133 + >
  134 + {{ record.approvalResult || '无' }}
  135 + </el-tag>
  136 + </div>
  137 + <div class="record-opinion" v-if="record.approvalOpinion">
  138 + 意见:{{ record.approvalOpinion }}
  139 + </div>
  140 + <div class="record-time" v-if="record.approvalTime">
  141 + 时间:{{ formatDateTime(record.approvalTime) }}
  142 + </div>
  143 + </div>
  144 + </div>
  145 + </div>
  146 + </div>
  147 + </div>
  148 + </el-card>
  149 +
  150 + <!-- 当前审批人信息 -->
  151 + <el-card class="info-card" shadow="hover" v-if="currentApprovers && currentApprovers.length > 0">
  152 + <div slot="header" class="card-header">
  153 + <i class="el-icon-user-solid"></i>
  154 + <span class="card-title">当前审批人</span>
  155 + </div>
  156 + <div class="current-approvers">
  157 + <el-tag
  158 + v-for="approver in currentApprovers"
  159 + :key="approver.userId"
  160 + type="warning"
  161 + size="medium"
  162 + style="margin-right: 8px;"
  163 + >
  164 + {{ approver.userName || '无' }}
  165 + </el-tag>
  166 + </div>
  167 + </el-card>
  168 +
  169 + <!-- 退回原因 -->
  170 + <el-card class="info-card" shadow="hover" v-if="returnedReason">
  171 + <div slot="header" class="card-header">
  172 + <i class="el-icon-warning"></i>
  173 + <span class="card-title">退回原因</span>
  174 + </div>
  175 + <div class="returned-reason">
  176 + {{ returnedReason }}
  177 + </div>
  178 + </el-card>
  179 +
  180 + <!-- 审批操作区域 -->
  181 + <el-card class="info-card" shadow="hover" v-if="canApprove">
  182 + <div slot="header" class="card-header">
  183 + <i class="el-icon-edit"></i>
  184 + <span class="card-title">审批操作</span>
  185 + </div>
  186 + <el-form :model="approvalForm" label-width="100px" label-position="right">
  187 + <el-form-item label="审批结果" required>
  188 + <el-radio-group v-model="approvalForm.result">
  189 + <el-radio label="通过">通过</el-radio>
  190 + <el-radio label="不通过">不通过</el-radio>
  191 + <el-radio label="退回">退回</el-radio>
  192 + </el-radio-group>
  193 + </el-form-item>
  194 + <el-form-item label="审批意见">
  195 + <el-input
  196 + v-model="approvalForm.opinion"
  197 + type="textarea"
  198 + :rows="4"
  199 + placeholder="请输入审批意见"
  200 + />
  201 + </el-form-item>
  202 + </el-form>
  203 + </el-card>
  204 + </div>
  205 + <span slot="footer" class="dialog-footer">
  206 + <el-button @click="visible = false">关 闭</el-button>
  207 + <el-button
  208 + type="primary"
  209 + @click="handleApprove"
  210 + :loading="approving"
  211 + v-if="canApprove"
  212 + >
  213 + 提交审批
  214 + </el-button>
  215 + </span>
  216 + </el-dialog>
  217 +</template>
  218 +
  219 +<script>
  220 +import request from '@/utils/request'
  221 +
  222 +export default {
  223 + name: 'DetailDialog',
  224 + data() {
  225 + return {
  226 + visible: false,
  227 + loading: false,
  228 + approving: false,
  229 + formData: null,
  230 + nodes: [],
  231 + currentApprovers: [],
  232 + currentNodeOrder: 0,
  233 + approvalStatus: '',
  234 + returnedReason: null,
  235 + approvalForm: {
  236 + result: '通过',
  237 + opinion: ''
  238 + }
  239 + }
  240 + },
  241 + computed: {
  242 + canApprove() {
  243 + // 判断是否可以审批:状态为"审批中"且当前用户是当前审批人
  244 + if (this.approvalStatus !== '审批中') {
  245 + return false
  246 + }
  247 + // 这里可以根据实际登录用户信息判断
  248 + // 暂时返回true,实际应该判断当前登录用户是否在currentApprovers中
  249 + return true
  250 + }
  251 + },
  252 + methods: {
  253 + init(id) {
  254 + this.visible = true
  255 + this.loading = true
  256 + this.formData = null
  257 + this.nodes = []
  258 + this.currentApprovers = []
  259 + this.currentNodeOrder = 0
  260 + this.approvalStatus = ''
  261 + this.returnedReason = null
  262 + this.approvalForm = {
  263 + result: '通过',
  264 + opinion: ''
  265 + }
  266 + this.getDetail(id)
  267 + },
  268 +
  269 + async getDetail(id) {
  270 + try {
  271 + const response = await request({
  272 + url: `/api/Extend/LqReimbursementApplication/${id}`,
  273 + method: 'GET'
  274 + })
  275 +
  276 + if (response.code === 200 && response.data) {
  277 + this.formData = response.data.form || null
  278 + this.nodes = response.data.nodes || []
  279 + this.currentApprovers = response.data.currentApprovers || []
  280 + this.currentNodeOrder = response.data.currentNodeOrder || 0
  281 + this.approvalStatus = response.data.approvalStatus || ''
  282 + this.returnedReason = response.data.returnedReason || null
  283 + } else {
  284 + this.$message.error(response.msg || '获取详情失败')
  285 + }
  286 + } catch (error) {
  287 + console.error('获取详情失败:', error)
  288 + this.$message.error('获取详情失败')
  289 + } finally {
  290 + this.loading = false
  291 + }
  292 + },
  293 +
  294 + async handleApprove() {
  295 + if (!this.approvalForm.result) {
  296 + this.$message.warning('请选择审批结果')
  297 + return
  298 + }
  299 +
  300 + this.approving = true
  301 + try {
  302 + const response = await request({
  303 + url: `/api/Extend/LqReimbursementApplication/${this.formData.id}/Actions/Approve`,
  304 + method: 'POST',
  305 + data: {
  306 + result: this.approvalForm.result,
  307 + opinion: this.approvalForm.opinion || ''
  308 + }
  309 + })
  310 +
  311 + if (response.code === 200) {
  312 + this.$message.success('审批成功')
  313 + this.visible = false
  314 + this.$emit('refresh')
  315 + } else {
  316 + this.$message.error(response.msg || '审批失败')
  317 + }
  318 + } catch (error) {
  319 + console.error('审批失败:', error)
  320 + this.$message.error('审批失败')
  321 + } finally {
  322 + this.approving = false
  323 + }
  324 + },
  325 +
  326 + handleClose() {
  327 + this.visible = false
  328 + this.formData = null
  329 + this.nodes = []
  330 + this.currentApprovers = []
  331 + this.currentNodeOrder = 0
  332 + this.approvalStatus = ''
  333 + this.returnedReason = null
  334 + this.approvalForm = {
  335 + result: '通过',
  336 + opinion: ''
  337 + }
  338 + },
  339 +
  340 + formatMoney(amount) {
  341 + if (!amount) return '无'
  342 + return `¥${Number(amount).toLocaleString('zh-CN', {
  343 + minimumFractionDigits: 2,
  344 + maximumFractionDigits: 2
  345 + })}`
  346 + },
  347 +
  348 + formatDateTime(dateTime) {
  349 + if (!dateTime) return '无'
  350 + // 如果是时间戳(数字),需要转换
  351 + if (typeof dateTime === 'number') {
  352 + const date = new Date(dateTime)
  353 + const year = date.getFullYear()
  354 + const month = String(date.getMonth() + 1).padStart(2, '0')
  355 + const day = String(date.getDate()).padStart(2, '0')
  356 + const hours = String(date.getHours()).padStart(2, '0')
  357 + const minutes = String(date.getMinutes()).padStart(2, '0')
  358 + const seconds = String(date.getSeconds()).padStart(2, '0')
  359 + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  360 + }
  361 + // 如果是字符串,直接返回
  362 + const date = new Date(dateTime)
  363 + if (isNaN(date.getTime())) return dateTime
  364 + const year = date.getFullYear()
  365 + const month = String(date.getMonth() + 1).padStart(2, '0')
  366 + const day = String(date.getDate()).padStart(2, '0')
  367 + const hours = String(date.getHours()).padStart(2, '0')
  368 + const minutes = String(date.getMinutes()).padStart(2, '0')
  369 + const seconds = String(date.getSeconds()).padStart(2, '0')
  370 + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  371 + },
  372 +
  373 + getStatusType(status) {
  374 + const statusMap = {
  375 + '待审批': 'info',
  376 + '审批中': 'warning',
  377 + '已通过': 'success',
  378 + '未通过': 'danger',
  379 + '已退回': 'warning'
  380 + }
  381 + return statusMap[status] || ''
  382 + },
  383 +
  384 + getRecordType(result) {
  385 + const typeMap = {
  386 + '待审批': 'info',
  387 + '通过': 'success',
  388 + '不通过': 'danger',
  389 + '退回': 'warning'
  390 + }
  391 + return typeMap[result] || ''
  392 + }
  393 + }
  394 +}
  395 +</script>
  396 +
  397 +<style lang="scss" scoped>
  398 +.detail-content {
  399 + max-height: 70vh;
  400 + overflow-y: auto;
  401 +}
  402 +
  403 +.info-card {
  404 + margin-bottom: 20px;
  405 +
  406 + .card-header {
  407 + display: flex;
  408 + align-items: center;
  409 + gap: 8px;
  410 + font-weight: 600;
  411 + color: #303133;
  412 +
  413 + i {
  414 + font-size: 18px;
  415 + color: #409EFF;
  416 + }
  417 + }
  418 +
  419 + .info-item {
  420 + margin-bottom: 16px;
  421 + display: flex;
  422 + align-items: center;
  423 +
  424 + .info-label {
  425 + min-width: 120px;
  426 + color: #606266;
  427 + font-weight: 500;
  428 + }
  429 +
  430 + .info-value {
  431 + color: #303133;
  432 + flex: 1;
  433 +
  434 + &.amount {
  435 + color: #F56C6C;
  436 + font-weight: 600;
  437 + font-size: 16px;
  438 + }
  439 + }
  440 + }
  441 +}
  442 +
  443 +.approval-flow {
  444 + .flow-node {
  445 + margin-bottom: 24px;
  446 + padding: 16px;
  447 + border: 1px solid #e4e7ed;
  448 + border-radius: 8px;
  449 + background: #fafafa;
  450 + transition: all 0.3s;
  451 +
  452 + &.node-active {
  453 + border-color: #409EFF;
  454 + background: #ecf5ff;
  455 + }
  456 +
  457 + &.node-completed {
  458 + border-color: #67C23A;
  459 + background: #f0f9ff;
  460 + }
  461 +
  462 + &.node-pending {
  463 + border-color: #e4e7ed;
  464 + background: #fafafa;
  465 + opacity: 0.6;
  466 + }
  467 +
  468 + .node-header {
  469 + display: flex;
  470 + align-items: center;
  471 + margin-bottom: 12px;
  472 +
  473 + .node-order {
  474 + width: 32px;
  475 + height: 32px;
  476 + line-height: 32px;
  477 + text-align: center;
  478 + background: #409EFF;
  479 + color: #fff;
  480 + border-radius: 50%;
  481 + font-weight: 600;
  482 + margin-right: 12px;
  483 + }
  484 +
  485 + .node-info {
  486 + flex: 1;
  487 +
  488 + .node-name {
  489 + font-size: 16px;
  490 + font-weight: 600;
  491 + color: #303133;
  492 + margin-bottom: 8px;
  493 + }
  494 +
  495 + .node-type {
  496 + display: flex;
  497 + gap: 8px;
  498 + }
  499 + }
  500 + }
  501 +
  502 + .approvers-list {
  503 + margin-bottom: 12px;
  504 + display: flex;
  505 + align-items: flex-start;
  506 +
  507 + .approvers-label {
  508 + min-width: 80px;
  509 + color: #606266;
  510 + font-weight: 500;
  511 + }
  512 +
  513 + .approvers-items {
  514 + flex: 1;
  515 + }
  516 + }
  517 +
  518 + .approval-records {
  519 + margin-top: 12px;
  520 + padding-top: 12px;
  521 + border-top: 1px solid #e4e7ed;
  522 +
  523 + .records-label {
  524 + color: #606266;
  525 + font-weight: 500;
  526 + margin-bottom: 8px;
  527 + }
  528 +
  529 + .records-list {
  530 + .record-item {
  531 + padding: 8px;
  532 + margin-bottom: 8px;
  533 + background: #fff;
  534 + border-radius: 4px;
  535 + border-left: 3px solid #409EFF;
  536 +
  537 + .record-header {
  538 + display: flex;
  539 + justify-content: space-between;
  540 + align-items: center;
  541 + margin-bottom: 4px;
  542 +
  543 + .record-approver {
  544 + font-weight: 500;
  545 + color: #303133;
  546 + }
  547 + }
  548 +
  549 + .record-opinion {
  550 + color: #606266;
  551 + font-size: 14px;
  552 + margin-bottom: 4px;
  553 + }
  554 +
  555 + .record-time {
  556 + color: #909399;
  557 + font-size: 12px;
  558 + }
  559 + }
  560 + }
  561 + }
  562 + }
  563 +}
  564 +
  565 +.current-approvers {
  566 + padding: 12px;
  567 + background: #fff3cd;
  568 + border-radius: 4px;
  569 +}
  570 +
  571 +.returned-reason {
  572 + padding: 12px;
  573 + background: #fef0f0;
  574 + border-radius: 4px;
  575 + color: #F56C6C;
  576 + line-height: 1.6;
  577 +}
  578 +</style>
  579 +
antis-ncc-admin/src/views/lqReimbursementApplication/index.vue
1 -<template>  
2 - <div class="NCC-common-layout">  
3 - <div class="NCC-common-layout-center">  
4 - <el-row class="NCC-common-search-box" :gutter="16">  
5 - <el-form @submit.native.prevent>  
6 -  
7 - <el-col :span="6">  
8 - <el-form-item label="申请时间">  
9 - <el-date-picker v-model="query.applicationTime" type="daterange" value-format="timestamp" format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期">  
10 - </el-date-picker>  
11 - </el-form-item>  
12 - </el-col>  
13 - <el-col :span="6">  
14 - <el-form-item label="申请人">  
15 - <userSelect v-model="query.applicationUserId" placeholder="请选择申请人" clearable />  
16 - </el-form-item>  
17 - </el-col>  
18 - <el-col :span="6">  
19 - <el-form-item label="门店">  
20 - <el-select v-model="query.applicationStoreId" placeholder="请选择门店" clearable filterable style="width: 100%">  
21 - <el-option  
22 - v-for="store in storeOptions"  
23 - :key="store.id"  
24 - :label="store.dm"  
25 - :value="store.id">  
26 - </el-option>  
27 - </el-select>  
28 - </el-form-item>  
29 - </el-col>  
30 - <template v-if="showAll">  
31 - <el-col :span="6">  
32 - <el-form-item label="审批状态">  
33 - <el-select v-model="query.approveStatus" placeholder="请选择审批状态" clearable style="width: 100%">  
34 - <el-option label="已审批" value="已审批"></el-option>  
35 - <el-option label="未通过" value="未通过"></el-option>  
36 - <el-option label="未审批" value="未审批"></el-option>  
37 - </el-select>  
38 - </el-form-item>  
39 - </el-col>  
40 - <!-- <el-col :span="6">  
41 - <el-form-item label="审批时间">  
42 - <el-date-picker v-model="query.approveTime" type="daterange" value-format="timestamp" format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期">  
43 - </el-date-picker>  
44 - </el-form-item>  
45 - </el-col> -->  
46 -  
47 - <!-- <el-col :span="6">  
48 - <el-form-item label="总金额">  
49 - <el-input v-model="query.amount" placeholder="总金额" clearable />  
50 - </el-form-item>  
51 - </el-col> -->  
52 - <!-- <el-col :span="6">  
53 - <el-form-item label="审批人">  
54 - <userSelect v-model="query.approveUser" placeholder="请选择审批人" />  
55 - </el-form-item>  
56 - </el-col>  
57 - <el-col :span="6">  
58 - <el-form-item label="审批结果">  
59 - <el-input v-model="query.approveStatus" placeholder="审批结果" clearable />  
60 - </el-form-item>  
61 - </el-col> -->  
62 - <!-- <el-col :span="6">  
63 - <el-form-item label="关联购买编号">  
64 - <el-input v-model="query.purchaseRecordsId" placeholder="关联购买编号" clearable />  
65 - </el-form-item>  
66 - </el-col> -->  
67 - </template>  
68 - <el-col :span="6">  
69 - <el-form-item>  
70 - <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>  
71 - <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button>  
72 - <el-button type="text" icon="el-icon-arrow-down" @click="showAll=true" v-if="!showAll">展开</el-button>  
73 - <el-button type="text" icon="el-icon-arrow-up" @click="showAll=false" v-else>收起</el-button>  
74 - </el-form-item>  
75 - </el-col>  
76 - </el-form>  
77 - </el-row>  
78 - <div class="NCC-common-layout-main NCC-flex-main">  
79 - <div class="NCC-common-head">  
80 - <div>  
81 - <el-button type="primary" icon="el-icon-plus" @click="addOrUpdateHandle()">新增</el-button>  
82 - <el-button type="text" icon="el-icon-delete" @click="handleBatchRemoveDel()">批量删除</el-button>  
83 - <!-- <el-button type="text" icon="el-icon-download" @click="exportData()">导出</el-button>  
84 - <el-button type="text" icon="el-icon-delete" @click="handleBatchRemoveDel()">批量删除</el-button> -->  
85 - </div>  
86 - <div class="NCC-common-head-right">  
87 - <el-tooltip effect="dark" content="刷新" placement="top">  
88 - <el-link icon="icon-ym icon-ym-Refresh NCC-common-head-icon" :underline="false" @click="reset()" />  
89 - </el-tooltip>  
90 - <screenfull isContainer />  
91 - </div>  
92 - </div>  
93 - <NCC-table v-loading="listLoading" :data="list" has-c @selection-change="handleSelectionChange">  
94 - <!-- <el-table-column prop="id" label="申请编号" align="left" /> -->  
95 - <!-- <el-table-column prop="applicationUserId" label="申请人编号" align="left" /> -->  
96 - <el-table-column prop="applicationUserName" label="申请人" align="left" />  
97 - <el-table-column prop="applicationStoreId" label="门店" align="left">  
98 - <template slot-scope="scope">  
99 - <div class="store-info">  
100 - <i class="el-icon-shop"></i>  
101 - <span>{{ getStoreName(scope.row.applicationStoreId) || '无' }}</span>  
102 - </div>  
103 - </template>  
104 - </el-table-column>  
105 - <el-table-column prop="applicationTime" label="申请时间" align="left" :formatter="ncc.tableDateFormat" />  
106 - <el-table-column prop="amount" label="总金额" align="left" />  
107 - <el-table-column prop="approveStatus" label="审批状态" align="left"/>  
108 - <el-table-column prop="approveTime" label="审批时间" align="left" :formatter="ncc.tableDateFormat" />  
109 - <!-- <el-table-column prop="approveUser" label="审批人" align="left" />  
110 - <el-table-column prop="approveStatus" label="审批结果" align="left" /> -->  
111 - <!-- <el-table-column prop="purchaseRecordsId" label="关联购买编号" align="left" /> -->  
112 - <el-table-column label="操作" fixed="right" width="100">  
113 - <template slot-scope="scope">  
114 - <el-button type="text" v-if="scope.row.approveStatus === '未审批'" @click="addOrUpdateHandle(scope.row.id)" >编辑</el-button>  
115 - <el-button type="text" v-if="scope.row.approveStatus === '已审批'" @click="showDetail(scope.row.id)" >查看</el-button>  
116 - <!-- <el-button type="text" v-if="scope.row.approveStatus === '未审批'" @click="handleDel(scope.row.id)" class="NCC-table-delBtn" >删除</el-button> -->  
117 - </template>  
118 - </el-table-column>  
119 - </NCC-table>  
120 - <pagination :total="total" :page.sync="listQuery.currentPage" :limit.sync="listQuery.pageSize" @pagination="initData" /> 1 +<template>
  2 + <div class="app-container">
  3 + <!-- 页面头部 -->
  4 + <div class="page-header">
  5 + <div class="header-left">
  6 + <h2>报销申请管理</h2>
  7 + <p class="page-desc">管理报销申请,包括待办审批、所有申请列表等</p>
  8 + </div>
  9 + <div class="header-right">
  10 + <el-button
  11 + icon="el-icon-refresh"
  12 + @click="getList"
  13 + :loading="listLoading"
  14 + >
  15 + 刷新
  16 + </el-button>
  17 + </div>
  18 + </div>
  19 +
  20 + <!-- 标签页切换 -->
  21 + <div class="tabs-container">
  22 + <el-tabs v-model="activeTab" @tab-click="handleTabChange">
  23 + <el-tab-pane label="所有待办" name="allPending">
  24 + <template slot="label">
  25 + <span><i class="el-icon-s-order"></i> 所有待办</span>
  26 + </template>
  27 + </el-tab-pane>
  28 + <el-tab-pane label="我的待办" name="myPending">
  29 + <template slot="label">
  30 + <span><i class="el-icon-user"></i> 我的待办</span>
  31 + </template>
  32 + </el-tab-pane>
  33 + <el-tab-pane label="所有申请" name="all">
  34 + <template slot="label">
  35 + <span><i class="el-icon-document"></i> 所有申请</span>
  36 + </template>
  37 + </el-tab-pane>
  38 + </el-tabs>
  39 + </div>
  40 +
  41 + <!-- 搜索区域 -->
  42 + <div class="search-container">
  43 + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px" label-position="right">
  44 + <el-form-item label="申请门店ID" prop="applicationStoreId">
  45 + <el-input
  46 + v-model="queryParams.applicationStoreId"
  47 + placeholder="请输入申请门店ID"
  48 + clearable
  49 + style="width: 200px"
  50 + />
  51 + </el-form-item>
  52 + <template v-if="activeTab === 'all'">
  53 + <el-form-item label="申请编号" prop="id">
  54 + <el-input
  55 + v-model="queryParams.id"
  56 + placeholder="请输入申请编号"
  57 + clearable
  58 + style="width: 200px"
  59 + />
  60 + </el-form-item>
  61 + <el-form-item label="申请人编号" prop="applicationUserId">
  62 + <el-input
  63 + v-model="queryParams.applicationUserId"
  64 + placeholder="请输入申请人编号"
  65 + clearable
  66 + style="width: 200px"
  67 + />
  68 + </el-form-item>
  69 + <el-form-item label="申请人姓名" prop="applicationUserName">
  70 + <el-input
  71 + v-model="queryParams.applicationUserName"
  72 + placeholder="请输入申请人姓名"
  73 + clearable
  74 + style="width: 200px"
  75 + />
  76 + </el-form-item>
  77 + <el-form-item label="申请时间" prop="applicationTime">
  78 + <el-date-picker
  79 + v-model="queryParams.applicationTime"
  80 + type="daterange"
  81 + range-separator="至"
  82 + start-placeholder="开始日期"
  83 + end-placeholder="结束日期"
  84 + format="yyyy-MM-dd"
  85 + value-format="yyyy-MM-dd"
  86 + style="width: 240px"
  87 + />
  88 + </el-form-item>
  89 + <el-form-item label="金额" prop="amount">
  90 + <el-input
  91 + v-model="queryParams.amount"
  92 + placeholder="请输入金额"
  93 + clearable
  94 + style="width: 200px"
  95 + />
  96 + </el-form-item>
  97 + <el-form-item label="审批状态" prop="approveStatus">
  98 + <el-select
  99 + v-model="queryParams.approveStatus"
  100 + placeholder="请选择审批状态"
  101 + clearable
  102 + style="width: 200px"
  103 + >
  104 + <el-option label="待审批" value="待审批" />
  105 + <el-option label="审批中" value="审批中" />
  106 + <el-option label="已通过" value="已通过" />
  107 + <el-option label="未通过" value="未通过" />
  108 + <el-option label="已退回" value="已退回" />
  109 + </el-select>
  110 + </el-form-item>
  111 + <el-form-item label="购买记录编号" prop="purchaseRecordsId">
  112 + <el-input
  113 + v-model="queryParams.purchaseRecordsId"
  114 + placeholder="请输入购买记录编号"
  115 + clearable
  116 + style="width: 200px"
  117 + />
  118 + </el-form-item>
  119 + </template>
  120 + <el-form-item>
  121 + <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
  122 + <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
  123 + </el-form-item>
  124 + </el-form>
  125 + </div>
  126 +
  127 + <!-- 数据表格 -->
  128 + <div class="table-container">
  129 + <NCC-table
  130 + v-loading="listLoading"
  131 + :data="list"
  132 + border
  133 + stripe
  134 + height="calc(100vh - 500px)"
  135 + :header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
  136 + >
  137 + <!-- 申请编号 -->
  138 + <el-table-column label="申请编号" width="180" align="center">
  139 + <template slot-scope="scope">
  140 + <div class="id-item">
  141 + <i class="el-icon-document id-icon"></i>
  142 + <span>{{ scope.row.id || '无' }}</span>
  143 + </div>
  144 + </template>
  145 + </el-table-column>
  146 +
  147 + <!-- 申请人 -->
  148 + <el-table-column label="申请人" width="140" align="center">
  149 + <template slot-scope="scope">
  150 + <div class="user-item">
  151 + <i class="el-icon-user user-icon"></i>
  152 + <span>{{ scope.row.applicationUserName || '无' }}</span>
  153 + </div>
  154 + </template>
  155 + </el-table-column>
  156 +
  157 + <!-- 申请门店ID -->
  158 + <el-table-column label="申请门店ID" width="160" align="center">
  159 + <template slot-scope="scope">
  160 + <div class="store-item">
  161 + <i class="el-icon-shop store-icon"></i>
  162 + <span>{{ scope.row.applicationStoreId || '无' }}</span>
  163 + </div>
  164 + </template>
  165 + </el-table-column>
  166 +
  167 + <!-- 申请时间 -->
  168 + <el-table-column label="申请时间" width="180" align="center">
  169 + <template slot-scope="scope">
  170 + <div class="time-item">
  171 + <i class="el-icon-time time-icon"></i>
  172 + <span>{{ formatDateTime(scope.row.applicationTime) || '无' }}</span>
  173 + </div>
  174 + </template>
  175 + </el-table-column>
  176 +
  177 + <!-- 金额 -->
  178 + <el-table-column label="金额" width="140" align="center">
  179 + <template slot-scope="scope">
  180 + <div class="amount-item">
  181 + <i class="el-icon-money amount-icon"></i>
  182 + <span class="amount-value">{{ formatMoney(scope.row.amount) || '无' }}</span>
121 </div> 183 </div>
122 - </div>  
123 - <NCC-Form v-if="formVisible" ref="NCCForm" @refresh="refresh" />  
124 - <ExportBox v-if="exportBoxVisible" ref="ExportBox" @download="download" />  
125 - <DetailDialog v-if="detailVisible" ref="DetailDialog" @close="handleDetailClose" />  
126 - </div> 184 + </template>
  185 + </el-table-column>
  186 +
  187 + <!-- 审批状态 -->
  188 + <el-table-column label="审批状态" width="120" align="center">
  189 + <template slot-scope="scope">
  190 + <el-tag
  191 + :type="getStatusType(scope.row.approveStatus)"
  192 + size="small"
  193 + >
  194 + {{ scope.row.approveStatus || '无' }}
  195 + </el-tag>
  196 + </template>
  197 + </el-table-column>
  198 +
  199 + <!-- 当前审批人 -->
  200 + <el-table-column label="当前审批人" width="160" align="center" v-if="activeTab !== 'all'">
  201 + <template slot-scope="scope">
  202 + <div class="approver-item">
  203 + <i class="el-icon-user-solid approver-icon"></i>
  204 + <span>{{ scope.row.currentApprovers || '无' }}</span>
  205 + </div>
  206 + </template>
  207 + </el-table-column>
  208 +
  209 + <!-- 当前节点 -->
  210 + <el-table-column label="当前节点" width="120" align="center" v-if="activeTab !== 'all'">
  211 + <template slot-scope="scope">
  212 + <div class="node-item">
  213 + <i class="el-icon-s-order node-icon"></i>
  214 + <span>{{ scope.row.currentNodeOrder ? `第${scope.row.currentNodeOrder}节点` : '无' }}</span>
  215 + </div>
  216 + </template>
  217 + </el-table-column>
  218 +
  219 + <!-- 节点总数 -->
  220 + <el-table-column label="节点总数" width="100" align="center" v-if="activeTab !== 'all'">
  221 + <template slot-scope="scope">
  222 + <div class="node-count-item">
  223 + <i class="el-icon-s-data node-count-icon"></i>
  224 + <span>{{ scope.row.nodeCount || '无' }}</span>
  225 + </div>
  226 + </template>
  227 + </el-table-column>
  228 +
  229 + <!-- 操作 -->
  230 + <el-table-column label="操作" width="200" align="left" fixed="right">
  231 + <template slot-scope="scope">
  232 + <div class="action-buttons">
  233 + <el-button
  234 + type="text"
  235 + icon="el-icon-view"
  236 + @click="handleView(scope.row)"
  237 + size="small"
  238 + class="view-btn"
  239 + >
  240 + 查看
  241 + </el-button>
  242 + <el-button
  243 + type="text"
  244 + icon="el-icon-time"
  245 + @click="handleViewHistory(scope.row)"
  246 + size="small"
  247 + class="history-btn"
  248 + >
  249 + 审批历史
  250 + </el-button>
  251 + </div>
  252 + </template>
  253 + </el-table-column>
  254 + </NCC-table>
  255 + </div>
  256 +
  257 + <!-- 分页 -->
  258 + <div class="pagination-container">
  259 + <el-pagination
  260 + @size-change="handleSizeChange"
  261 + @current-change="handleCurrentChange"
  262 + :current-page="listQuery.currentPage"
  263 + :page-sizes="[10, 20, 50, 100]"
  264 + :page-size="listQuery.pageSize"
  265 + layout="total, sizes, prev, pager, next, jumper"
  266 + :total="total"
  267 + />
  268 + </div>
  269 +
  270 + <!-- 详情/审批弹窗 -->
  271 + <detail-dialog
  272 + v-if="detailVisible"
  273 + ref="DetailDialog"
  274 + @refresh="getList"
  275 + />
  276 +
  277 + <!-- 审批历史弹窗 -->
  278 + <approval-history-dialog
  279 + v-if="historyVisible"
  280 + ref="ApprovalHistoryDialog"
  281 + />
  282 + </div>
127 </template> 283 </template>
  284 +
128 <script> 285 <script>
129 - import request from '@/utils/request'  
130 - import { getDictionaryDataSelector } from '@/api/systemData/dictionary'  
131 - import { getStoreSelector } from '@/api/extend/store'  
132 - import NCCForm from './Form'  
133 - import ExportBox from './ExportBox'  
134 - import DetailDialog from './detail'  
135 - import { previewDataInterface } from '@/api/systemData/dataInterface'  
136 - export default {  
137 - components: { NCCForm, ExportBox, DetailDialog },  
138 - data() {  
139 - return {  
140 - showAll: false,  
141 - storeOptions: [],  
142 - storeMap: {},  
143 - detailVisible: false,  
144 - query: {  
145 - id:undefined,  
146 - applicationUserId:undefined,  
147 - applicationUserName:undefined,  
148 - applicationStoreId:undefined,  
149 - applicationTime:undefined,  
150 - amount:undefined,  
151 - approveUser:undefined,  
152 - approveStatus:undefined,  
153 - approveTime:undefined,  
154 - purchaseRecordsId:undefined,  
155 - },  
156 - list: [],  
157 - listLoading: true,  
158 - multipleSelection: [], total: 0,  
159 - listQuery: {  
160 - currentPage: 1,  
161 - pageSize: 20,  
162 - sort: "desc",  
163 - sidx: "",  
164 - },  
165 - formVisible: false,  
166 - exportBoxVisible: false,  
167 - columnList: [  
168 - { prop: 'id', label: '申请编号' },  
169 - { prop: 'applicationUserId', label: '申请人编号' },  
170 - { prop: 'applicationUserName', label: '申请人姓名' },  
171 - { prop: 'applicationStoreId', label: '申请门店' },  
172 - { prop: 'applicationTime', label: '申请时间' },  
173 - { prop: 'amount', label: '总金额' },  
174 - { prop: 'approveUser', label: '审批人' },  
175 - { prop: 'approveStatus', label: '审批结果' },  
176 - { prop: 'approveTime', label: '审批时间' },  
177 - { prop: 'purchaseRecordsId', label: '关联购买编号' },  
178 - ],  
179 - }  
180 - },  
181 - computed: {},  
182 - created() {  
183 - this.loadStoreOptions()  
184 - this.initData()  
185 - },  
186 - methods: {  
187 - // 加载门店列表  
188 - loadStoreOptions() {  
189 - request({  
190 - url: '/api/Extend/LqMdxx',  
191 - method: 'GET',  
192 - data: {  
193 - currentPage: 1,  
194 - pageSize: 1000  
195 - }  
196 - }).then(res => {  
197 - if (res.data && res.data.list) {  
198 - this.storeOptions = res.data.list;  
199 - }  
200 - }).catch(() => {  
201 - this.storeOptions = [];  
202 - });  
203 - },  
204 -  
205 - getStoreName(storeId) {  
206 - if (!storeId) return '无';  
207 - const store = this.storeOptions.find(item => item.id === storeId);  
208 - return store ? store.dm : '无';  
209 - },  
210 - initData() {  
211 - this.listLoading = true;  
212 - let _query = {  
213 - ...this.listQuery,  
214 - ...this.query  
215 - };  
216 - let query = {}  
217 - for (let key in _query) {  
218 - if (Array.isArray(_query[key])) {  
219 - query[key] = _query[key].join()  
220 - } else {  
221 - query[key] = _query[key]  
222 - }  
223 - }  
224 - request({  
225 - url: `/api/Extend/LqReimbursementApplication`,  
226 - method: 'GET',  
227 - data: query  
228 - }).then(res => {  
229 - this.list = res.data.list  
230 - this.total = res.data.pagination.total  
231 - this.listLoading = false  
232 - })  
233 - },  
234 - handleDel(id) {  
235 - this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {  
236 - type: 'warning'  
237 - }).then(() => {  
238 - request({  
239 - url: `/api/Extend/LqReimbursementApplication/${id}`,  
240 - method: 'DELETE'  
241 - }).then(res => {  
242 - this.$message({  
243 - type: 'success',  
244 - message: res.msg,  
245 - onClose: () => {  
246 - this.initData()  
247 - }  
248 - });  
249 - })  
250 - }).catch(() => {  
251 - });  
252 - },  
253 - handleSelectionChange(val) {  
254 - const res = val.map(item => item.id)  
255 - this.multipleSelection = res  
256 - },  
257 - handleBatchRemoveDel() {  
258 - if (!this.multipleSelection.length) {  
259 - this.$message({  
260 - type: 'error',  
261 - message: '请选择一条数据',  
262 - duration: 1500,  
263 - })  
264 - return  
265 - }  
266 - const ids = this.multipleSelection  
267 - this.$confirm('您确定要删除这些数据吗, 是否继续?', '提示', {  
268 - type: 'warning'  
269 - }).then(() => {  
270 - request({  
271 - url: `/api/Extend/LqReimbursementApplication/batchRemove`,  
272 - method: 'POST',  
273 - data: ids ,  
274 - }).then(res => {  
275 - this.$message({  
276 - type: 'success',  
277 - message: res.msg,  
278 - onClose: () => {  
279 - this.initData()  
280 - }  
281 - });  
282 - })  
283 - }).catch(() => { })  
284 - },  
285 - addOrUpdateHandle(id, isDetail) {  
286 - this.formVisible = true  
287 - this.$nextTick(() => {  
288 - this.$refs.NCCForm.init(id, isDetail)  
289 - })  
290 - },  
291 - exportData() {  
292 - this.exportBoxVisible = true  
293 - this.$nextTick(() => {  
294 - this.$refs.ExportBox.init(this.columnList)  
295 - })  
296 - },  
297 - download(data) {  
298 - let query = { ...data, ...this.listQuery, ...this.query }  
299 - request({  
300 - url: `/api/Extend/LqReimbursementApplication/Actions/Export`,  
301 - method: 'GET',  
302 - data: query  
303 - }).then(res => {  
304 - if (!res.data.url) return  
305 - window.location.href = this.define.comUrl + res.data.url  
306 - this.$refs.ExportBox.visible = false  
307 - this.exportBoxVisible = false  
308 - })  
309 - },  
310 - search() {  
311 - this.listQuery = {  
312 - currentPage: 1,  
313 - pageSize: 20,  
314 - sort: "desc",  
315 - sidx: "",  
316 - }  
317 - this.initData()  
318 - },  
319 - refresh(isrRefresh) {  
320 - this.formVisible = false  
321 - if (isrRefresh) this.reset()  
322 - },  
323 - reset() {  
324 - for (let key in this.query) {  
325 - this.query[key] = undefined  
326 - }  
327 - this.listQuery = {  
328 - currentPage: 1,  
329 - pageSize: 20,  
330 - sort: "desc",  
331 - sidx: "",  
332 - }  
333 - this.initData()  
334 - },  
335 - showDetail(id) {  
336 - this.detailVisible = true  
337 - this.$nextTick(() => {  
338 - this.$refs.DetailDialog.init(id)  
339 - })  
340 - },  
341 - handleDetailClose() {  
342 - this.detailVisible = false  
343 - }  
344 - } 286 +import request from '@/utils/request'
  287 +import DetailDialog from './detail-dialog.vue'
  288 +import ApprovalHistoryDialog from './approval-history-dialog.vue'
  289 +
  290 +export default {
  291 + name: 'LqReimbursementApplication',
  292 + components: {
  293 + DetailDialog,
  294 + ApprovalHistoryDialog
  295 + },
  296 + data() {
  297 + return {
  298 + activeTab: 'allPending', // 当前激活的标签页
  299 + listLoading: false,
  300 + list: [],
  301 + total: 0,
  302 + detailVisible: false,
  303 + historyVisible: false,
  304 + queryParams: {
  305 + applicationStoreId: '',
  306 + id: '',
  307 + applicationUserId: '',
  308 + applicationUserName: '',
  309 + applicationTime: null,
  310 + amount: '',
  311 + approveStatus: '',
  312 + purchaseRecordsId: ''
  313 + },
  314 + listQuery: {
  315 + currentPage: 1,
  316 + pageSize: 20,
  317 + sidx: 'applicationTime',
  318 + sort: 'desc'
  319 + }
345 } 320 }
  321 + },
  322 + created() {
  323 + this.getList()
  324 + },
  325 + methods: {
  326 + // 获取列表数据
  327 + async getList() {
  328 + this.listLoading = true
  329 + try {
  330 + let url = '/api/Extend/LqReimbursementApplication'
  331 +
  332 + // 根据标签页选择不同的接口
  333 + if (this.activeTab === 'allPending') {
  334 + url = '/api/Extend/LqReimbursementApplication/Actions/AllPendingApproval'
  335 + } else if (this.activeTab === 'myPending') {
  336 + url = '/api/Extend/LqReimbursementApplication/Actions/PendingApproval'
  337 + }
  338 +
  339 + const params = {
  340 + currentPage: this.listQuery.currentPage,
  341 + pageSize: this.listQuery.pageSize,
  342 + sidx: this.listQuery.sidx,
  343 + sort: this.listQuery.sort
  344 + }
  345 +
  346 + // 添加查询参数
  347 + if (this.queryParams.applicationStoreId) {
  348 + params.applicationStoreId = this.queryParams.applicationStoreId
  349 + }
  350 +
  351 + // 只有"所有申请"标签页才添加这些查询参数
  352 + if (this.activeTab === 'all') {
  353 + if (this.queryParams.id) {
  354 + params.id = this.queryParams.id
  355 + }
  356 + if (this.queryParams.applicationUserId) {
  357 + params.applicationUserId = this.queryParams.applicationUserId
  358 + }
  359 + if (this.queryParams.applicationUserName) {
  360 + params.applicationUserName = this.queryParams.applicationUserName
  361 + }
  362 + if (this.queryParams.applicationTime && this.queryParams.applicationTime.length === 2) {
  363 + params.applicationTime = `${this.queryParams.applicationTime[0]},${this.queryParams.applicationTime[1]}`
  364 + }
  365 + if (this.queryParams.amount) {
  366 + params.amount = this.queryParams.amount
  367 + }
  368 + if (this.queryParams.approveStatus) {
  369 + params.approveStatus = this.queryParams.approveStatus
  370 + }
  371 + if (this.queryParams.purchaseRecordsId) {
  372 + params.purchaseRecordsId = this.queryParams.purchaseRecordsId
  373 + }
  374 + }
  375 +
  376 + const response = await request({
  377 + url: url,
  378 + method: 'GET',
  379 + data: params
  380 + })
  381 +
  382 + if (response.code === 200) {
  383 + this.list = response.data.list || []
  384 + this.total = (response.data.pagination && response.data.pagination.Total) || 0
  385 + } else {
  386 + this.$message.error(response.msg || '获取列表失败')
  387 + this.list = []
  388 + this.total = 0
  389 + }
  390 + } catch (error) {
  391 + console.error('获取列表失败:', error)
  392 + this.$message.error('获取列表失败')
  393 + this.list = []
  394 + this.total = 0
  395 + } finally {
  396 + this.listLoading = false
  397 + }
  398 + },
  399 +
  400 + // 标签页切换
  401 + handleTabChange() {
  402 + this.listQuery.currentPage = 1
  403 + this.resetQuery()
  404 + },
  405 +
  406 + // 搜索
  407 + handleQuery() {
  408 + this.listQuery.currentPage = 1
  409 + this.getList()
  410 + },
  411 +
  412 + // 重置搜索
  413 + resetQuery() {
  414 + this.queryParams = {
  415 + applicationStoreId: '',
  416 + id: '',
  417 + applicationUserId: '',
  418 + applicationUserName: '',
  419 + applicationTime: null,
  420 + amount: '',
  421 + approveStatus: '',
  422 + purchaseRecordsId: ''
  423 + }
  424 + this.listQuery = {
  425 + currentPage: 1,
  426 + pageSize: 20,
  427 + sidx: 'applicationTime',
  428 + sort: 'desc'
  429 + }
  430 + this.getList()
  431 + },
  432 +
  433 + // 查看详情/审批
  434 + handleView(row) {
  435 + this.detailVisible = true
  436 + this.$nextTick(() => {
  437 + this.$refs.DetailDialog.init(row.id)
  438 + })
  439 + },
  440 +
  441 + // 查看审批历史
  442 + handleViewHistory(row) {
  443 + this.historyVisible = true
  444 + this.$nextTick(() => {
  445 + this.$refs.ApprovalHistoryDialog.init(row.id)
  446 + })
  447 + },
  448 +
  449 + // 分页大小改变
  450 + handleSizeChange(val) {
  451 + this.listQuery.pageSize = val
  452 + this.getList()
  453 + },
  454 +
  455 + // 当前页改变
  456 + handleCurrentChange(val) {
  457 + this.listQuery.currentPage = val
  458 + this.getList()
  459 + },
  460 +
  461 + // 格式化金额
  462 + formatMoney(amount) {
  463 + if (!amount) return '无'
  464 + return `¥${Number(amount).toLocaleString('zh-CN', {
  465 + minimumFractionDigits: 2,
  466 + maximumFractionDigits: 2
  467 + })}`
  468 + },
  469 +
  470 + // 格式化日期时间
  471 + formatDateTime(dateTime) {
  472 + if (!dateTime) return '无'
  473 + const date = new Date(dateTime)
  474 + const year = date.getFullYear()
  475 + const month = String(date.getMonth() + 1).padStart(2, '0')
  476 + const day = String(date.getDate()).padStart(2, '0')
  477 + const hours = String(date.getHours()).padStart(2, '0')
  478 + const minutes = String(date.getMinutes()).padStart(2, '0')
  479 + return `${year}-${month}-${day} ${hours}:${minutes}`
  480 + },
  481 +
  482 + // 获取状态类型
  483 + getStatusType(status) {
  484 + const statusMap = {
  485 + '待审批': 'info',
  486 + '审批中': 'warning',
  487 + '已通过': 'success',
  488 + '未通过': 'danger',
  489 + '已退回': 'warning'
  490 + }
  491 + return statusMap[status] || ''
  492 + }
  493 + }
  494 +}
346 </script> 495 </script>
  496 +
347 <style lang="scss" scoped> 497 <style lang="scss" scoped>
348 -.store-info { 498 +.app-container {
  499 + padding: 20px;
  500 + background: #f5f5f5;
  501 +}
  502 +
  503 +.page-header {
  504 + display: flex;
  505 + justify-content: space-between;
  506 + align-items: flex-start;
  507 + margin-bottom: 20px;
  508 + padding: 20px;
  509 + background: #fff;
  510 + border-radius: 8px;
  511 + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  512 +
  513 + .header-left {
  514 + h2 {
  515 + margin: 0 0 8px 0;
  516 + color: #303133;
  517 + font-size: 20px;
  518 + font-weight: 600;
  519 + }
  520 +
  521 + .page-desc {
  522 + margin: 0;
  523 + color: #909399;
  524 + font-size: 14px;
  525 + }
  526 + }
  527 +
  528 + .header-right {
  529 + display: flex;
  530 + gap: 12px;
  531 + }
  532 +}
  533 +
  534 +.tabs-container {
  535 + margin-bottom: 20px;
  536 + padding: 20px;
  537 + background: #fff;
  538 + border-radius: 8px;
  539 + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  540 +}
  541 +
  542 +.search-container {
  543 + padding: 20px;
  544 + background: #fff;
  545 + border-radius: 8px;
  546 + margin-bottom: 20px;
  547 + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  548 +}
  549 +
  550 +.table-container {
  551 + background: #fff;
  552 + border-radius: 8px;
  553 + padding: 20px;
  554 + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  555 + margin-bottom: 20px;
  556 +}
  557 +
  558 +// 表格项样式
  559 +.id-item,
  560 +.user-item,
  561 +.store-item,
  562 +.time-item,
  563 +.amount-item,
  564 +.approver-item,
  565 +.node-item,
  566 +.node-count-item {
349 display: flex; 567 display: flex;
350 align-items: center; 568 align-items: center;
  569 + justify-content: center;
351 gap: 6px; 570 gap: 6px;
352 -  
353 - i { 571 +
  572 + .id-icon {
  573 + color: #409EFF;
  574 + font-size: 16px;
  575 + }
  576 +
  577 + .user-icon {
354 color: #67C23A; 578 color: #67C23A;
355 - font-size: 14px; 579 + font-size: 16px;
356 } 580 }
357 - 581 +
  582 + .store-icon {
  583 + color: #67C23A;
  584 + font-size: 16px;
  585 + }
  586 +
  587 + .time-icon {
  588 + color: #909399;
  589 + font-size: 16px;
  590 + }
  591 +
  592 + .amount-icon {
  593 + color: #F56C6C;
  594 + font-size: 16px;
  595 + }
  596 +
  597 + .approver-icon {
  598 + color: #409EFF;
  599 + font-size: 16px;
  600 + }
  601 +
  602 + .node-icon {
  603 + color: #909399;
  604 + font-size: 16px;
  605 + }
  606 +
  607 + .node-count-icon {
  608 + color: #909399;
  609 + font-size: 16px;
  610 + }
  611 +
358 span { 612 span {
359 - color: #303133; 613 + color: #606266;
360 } 614 }
361 } 615 }
362 -</style>  
363 \ No newline at end of file 616 \ No newline at end of file
  617 +
  618 +.amount-value {
  619 + font-weight: 600;
  620 + color: #F56C6C;
  621 +}
  622 +
  623 +// 操作按钮样式
  624 +.action-buttons {
  625 + display: flex;
  626 + align-items: center;
  627 + gap: 8px;
  628 +
  629 + .view-btn {
  630 + color: #409EFF;
  631 +
  632 + &:hover {
  633 + color: #66b1ff;
  634 + }
  635 + }
  636 +
  637 + .history-btn {
  638 + color: #909399;
  639 +
  640 + &:hover {
  641 + color: #606266;
  642 + }
  643 + }
  644 +}
  645 +
  646 +.pagination-container {
  647 + display: flex;
  648 + justify-content: center;
  649 + padding: 20px;
  650 + background: #fff;
  651 + border-radius: 8px;
  652 + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  653 +}
  654 +</style>
绿纤uni-app/common/config.js
@@ -10,8 +10,8 @@ const ENV_CONFIG = { @@ -10,8 +10,8 @@ const ENV_CONFIG = {
10 // 正式环境 10 // 正式环境
11 production: { 11 production: {
12 name: '正式环境', 12 name: '正式环境',
13 - // apiBaseUrl: 'http://erp_test.lvqianmeiye.com',  
14 - apiBaseUrl: 'https://erp.lvqianmeiye.com', 13 + apiBaseUrl: 'http://erp_test.lvqianmeiye.com',
  14 + // apiBaseUrl: 'https://erp.lvqianmeiye.com',
15 description: '生产环境服务器' 15 description: '生产环境服务器'
16 } 16 }
17 }; 17 };