master
lynn 7 months ago
parent de00a1c07a
commit 147d26a76e

@ -14,7 +14,7 @@
<!-- Pre-payment Form -->
<div v-if="currentForm === 'pre'" class="payment-form">
<div v-if="getBeforeForms" v-html="getBeforeForms"></div>
<div v-else class="no-form-message">暂无事前支付表格内容</div>
<div v-else class="no-form-message">暂无事前审批表格内容</div>
</div>
<!-- Post-payment Form -->
@ -65,16 +65,98 @@ export default {
this.$Message.error('获取付款详情失败')
}
},
replaceControls(element) {
//
const inputs = element.getElementsByTagName('input')
Array.from(inputs).forEach(input => {
const span = document.createElement('span')
let displayText = input.value || ''
//
if (input.type === 'checkbox' || input.type === 'radio') {
//
const checkedInput = element.querySelector(`input[name="${input.name}"]:checked`)
if (checkedInput) {
// label使label
const label = element.querySelector(`label[for="${checkedInput.id}"]`)
displayText = label ? label.textContent : checkedInput.value || ''
} else {
displayText = ''
}
} else if (input.type === 'date') {
displayText = input.value ? new Date(input.value).toLocaleDateString() : ''
}
span.textContent = displayText
//
span.style.cssText = window.getComputedStyle(input).cssText
span.style.display = 'inline-block'
span.style.width = input.offsetWidth + 'px'
span.style.height = input.offsetHeight + 'px'
span.style.border = 'none'
span.style.backgroundColor = 'transparent'
input.parentNode.replaceChild(span, input)
})
//
const selects = element.getElementsByTagName('select')
Array.from(selects).forEach(select => {
const span = document.createElement('span')
span.textContent = select.options[select.selectedIndex]?.text || ''
//
span.style.cssText = window.getComputedStyle(select).cssText
span.style.display = 'inline-block'
span.style.width = select.offsetWidth + 'px'
span.style.height = select.offsetHeight + 'px'
span.style.border = 'none'
span.style.backgroundColor = 'transparent'
select.parentNode.replaceChild(span, select)
})
//
const textareas = element.getElementsByTagName('textarea')
Array.from(textareas).forEach(textarea => {
const span = document.createElement('span')
span.textContent = textarea.value || ''
//
span.style.cssText = window.getComputedStyle(textarea).cssText
span.style.display = 'inline-block'
span.style.width = textarea.offsetWidth + 'px'
span.style.height = textarea.offsetHeight + 'px'
span.style.border = 'none'
span.style.backgroundColor = 'transparent'
textarea.parentNode.replaceChild(span, textarea)
})
},
async print() {
try {
const canvas = await html2canvas(this.$refs['printtable'], {
//
const tempContainer = document.createElement('div')
tempContainer.style.position = 'absolute'
tempContainer.style.left = '-9999px'
tempContainer.style.top = '-9999px'
document.body.appendChild(tempContainer)
//
const originalContent = this.$refs['printtable'].cloneNode(true)
tempContainer.appendChild(originalContent)
//
this.replaceControls(tempContainer)
// 使
const canvas = await html2canvas(tempContainer, {
backgroundColor: null,
useCORS: true,
})
//
document.body.removeChild(tempContainer)
printJS({
printable: canvas.toDataURL(),
type: 'image',
documentTitle: `苏州市河道管理处${this.currentForm === 'pre' ? '事前' : '事后'}支付表格`,
documentTitle: `苏州市河道管理处${this.currentForm === 'pre' ? '事前审批表格' : '事后支付表格'}`,
style: '@page{margin:auto;}'
})
} catch (error) {

@ -3,6 +3,34 @@
<lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="合同列表">
<div slot="content"></div>
<slot>
<!-- 修改为新增合同按钮 -->
<div class="category-buttons">
<Button
type="primary"
size="large"
class="category-button"
@click="handleAddContractByCategory('contract')"
>
新增合同类
</Button>
<Button
type="primary"
size="large"
class="category-button"
@click="handleAddContractByCategory('reimbursement')"
>
新增报销类
</Button>
<Button
type="primary"
size="large"
class="category-button"
@click="handleAddContractByCategory('other')"
>
新增其他支出类
</Button>
</div>
<div class="selects">
<div>
<span style="padding: 0 6px;word-break: keep-all;">关键字</span>
@ -140,7 +168,6 @@
</Select>
</div>
<Button style="margin-left: 10px" type="primary" @click="handleAddContract"></Button>
<Button style="margin-left: 10px" type="primary" @click="getContracts"></Button>
<Button ghost style="margin-left: 10px" type="primary"
@click=" select = {showDatePicker:'',ageIndex:1,startDate:'',endDate:'',type:'',department:'',purchaseModality:'',purchaseMethods:'',priceMin:null,priceMax:null,status:''}">
@ -281,7 +308,7 @@
<div v-show="currentStep === 1" class="step-content">
<div class="form-group" v-if="categoryOptions && categoryOptions.length > 0">
<label class="form-label">分类</label>
<Select v-model="form.category" @on-change="handleCategoryChange" placeholder="请选择分类" class="form-input">
<Select v-model="form.category" @on-change="handleCategoryChange" placeholder="请选择分类" class="form-input" disabled>
<Option v-for="item in categoryOptions" :key="item.id" :value="item.id">{{ item.value || item.name }}</Option>
</Select>
</div>
@ -817,6 +844,7 @@ export default {
}
return {
selectedCategory: 'contract', //
userList: ["liuxiangyu", "zhushulan", "admin", "jiangjiao"],
window: {
width: 0,
@ -3240,6 +3268,53 @@ export default {
}
this.showPaymentFormPreview = false;
},
//
handleCategorySelect(category) {
this.selectedCategory = category;
//
this.select.category = category;
this.getContracts();
},
//
async handleAddContractByCategory(category) {
// loading
this.loading = true;
try {
//
this.isShowAdd = true;
this.isEditMode = false;
this.isFromPayment = false;
//
await this.getCategoryOptions();
//
this.resetForm();
//
if (this.categoryOptions && this.categoryOptions.length > 0) {
//
const categoryOption = this.categoryOptions.find(item => {
const name = item.name || item.value || '';
return name.includes(category === 'contract' ? '合同' :
category === 'reimbursement' ? '报销' : '其他支出');
});
if (categoryOption) {
this.form.category = categoryOption.id;
//
this.handleCategoryChange();
}
}
} catch (error) {
console.error('加载数据失败:', error);
this.$message.error('加载数据失败');
} finally {
// loading
this.loading = false;
}
},
},
mounted() {
this.window.width = screen.availWidth * 0.95
@ -3689,6 +3764,38 @@ export default {
}
}
}
//
.category-buttons {
display: flex;
justify-content: center;
gap: 20px;
margin-bottom: 20px;
padding: 10px 0;
.category-button {
min-width: 180px;
height: 48px;
font-size: 16px;
font-weight: 500;
border-radius: 8px;
transition: all 0.3s ease;
background: #2d8cf0;
border-color: #2d8cf0;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
background: #2b85e4;
border-color: #2b85e4;
}
&:active {
transform: translateY(0);
box-shadow: none;
}
}
}
</style>
<style scoped lang="scss">

@ -4,6 +4,33 @@
<div slot="content"></div>
<slot>
<div class="selects">
<div>
<span style="padding: 0 6px;word-break: keep-all;">
合同分类
</span>
<Select v-model="select.contract_category" @on-change="handleCategoryChange" disabled placeholder="请选择合同分类" style="width:140px;">
<Option v-for="item in categoryOptions" :key="item.id" :value="item.id">{{ item.value || item.name }}</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
事务类型
</span>
<Select v-model="select.work_type" @on-change="handleTransactionTypeChange" multiple clearable placeholder="请选择事务类型" style="width:140px;">
<Option v-for="item in transactionTypes" :key="item.id" :value="item.id">{{ item.value || item.name }}</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">
合同类型
</span>
<Select v-model="select.contract_type" @on-change="handleContractTypeChange" multiple clearable placeholder="请选择合同类型" style="width:140px;">
<Option v-for="item in contractTypes" :key="item.id" :value="item.id">{{ item.value || item.name }}</Option>
</Select>
</div>
<div>
<span style="padding: 0 6px;word-break: keep-all;">关键字</span>
<span>
@ -411,6 +438,7 @@
import {
getInfo
} from '@/api/user.js'
import { getContractCategoryTemplateBaseConfig } from "@/api/businessConfig/businessConfig"
import editor from "./components/editorContract"
import detail from "./components/detailContract"
@ -489,7 +517,10 @@
showDatePickerBao: "",
start_assurance_expire: "",
end_assurance_expire: "",
is_contract: ''
is_contract: '',
contract_category: '',
work_type: '',
contract_type: ''
},
types: [{
label: '服务',
@ -982,6 +1013,11 @@
plansPageIndex: 1,
isShowEditor: false,
contractCategories: [], //
transactionTypes: [], //
contractTypes: [], //
categoryOptions: [], //
purchaseMethodsMap: {}, //
}
},
created() {
@ -1509,33 +1545,136 @@
});
});
},
//
async getCategoryOptions() {
try {
//
const res = await getContractCategoryTemplateBaseConfig()
if (res.errcode !== undefined) {
this.$message.error(res.errmsg || '获取分类配置失败')
return
}
//
this.purchaseMethodsMap = res.purchase_methods || {}
// -
this.categoryOptions = res.map?.[0]?.children || []
// children
const processChildren = (items) => {
if (!items) return
items.forEach(item => {
if (item.children) {
// id name/value
item.children = item.children.map(child => ({
id: child.id,
name: child.name || child.value, // value
value: child.value || child.name, // value
children: child.children || []
}))
processChildren(item.children)
}
})
}
// children
processChildren(this.categoryOptions)
//
this.updateDropdownOptions()
} catch (error) {
console.error('获取分类配置失败:', error)
this.$message.error('获取分类配置失败')
}
},
//
updateDropdownOptions() {
//
this.transactionTypes = []
this.contractTypes = []
//
const selectedCategory = this.categoryOptions.find(item => item.id === this.select.contract_category)
if (!selectedCategory) return
//
this.transactionTypes = selectedCategory.children || []
//
if (!this.select.work_type || this.select.work_type.length === 0) {
this.select.work_type = this.transactionTypes.map(item => item.id)
}
//
const selectedTransactionTypes = this.transactionTypes.filter(item =>
this.select.work_type.includes(item.id)
)
//
this.contractTypes = selectedTransactionTypes.reduce((acc, curr) => {
return [...acc, ...(curr.children || [])]
}, [])
// ""(id=140)
if (!this.select.contract_type || this.select.contract_type.length === 0) {
this.select.contract_type = this.contractTypes
.filter(item => item.id !== 140) // ""
.map(item => item.id)
}
},
//
handleCategoryChange() {
// updateDropdownOptions
this.select.work_type = []
this.select.contract_type = []
this.updateDropdownOptions()
},
//
handleTransactionTypeChange() {
// updateDropdownOptions
this.select.contract_type = []
this.updateDropdownOptions()
},
//
handleContractTypeChange() {
this.updateDropdownOptions()
},
},
mounted() {
this.window.width = screen.availWidth * 0.95
this.window.height = screen.availHeight * 0.95
this.window.top = (window.screen.height - 30 - this.window.height) / 2
this.window.left = (window.screen.width - 10 - this.window.width) / 2
this.window.width = screen.availWidth * 0.95;
this.window.height = screen.availHeight * 0.95;
this.window.top = (window.screen.height - 30 - this.window.height) / 2;
this.window.left = (window.screen.width - 10 - this.window.width) / 2;
let that = this;
getInfo().then(response => {
console.log(response)
console.log(response);
this.user = response;
if (that.userList.indexOf(response.username) != -1) {
that.hasEdit = true;
}
}).catch(error => {})
this.getPurchaseType()
this.getContracts()
this.getDepartment()
this.getPurchaseWay()
this.getMoneyWay()
}).catch(error => {});
this.getPurchaseType();
this.getContracts();
this.getDepartment();
this.getPurchaseWay();
this.getMoneyWay();
//
this.getCategoryOptions().then(() => {
//
if (this.categoryOptions && this.categoryOptions.length > 0) {
this.select.contract_category = this.categoryOptions[0].id;
this.handleCategoryChange();
}
});
//
window.onfocus = () => {
this.getContracts()
}
this.getContracts();
};
},
destroyed() {
window.onfocus = null

@ -40,6 +40,15 @@
ghost>下级部门</Button>
<Button type="error" @click="del(scope.row)" size="small" style="margin-left: 10px;" ghost>删除</Button>
<Button type="primary" @click="edit(scope.row)" size="small" style="margin-left: 10px;" ghost>编辑</Button>
<Button
:type="scope.row.status === 1 ? 'warning' : 'success'"
@click="toggleStatus(scope.row)"
size="small"
style="margin-left: 10px;"
ghost
>
{{ scope.row.status === 1 ? '禁用' : '启用' }}
</Button>
</template>
</el-table-column>
</el-table>
@ -81,7 +90,8 @@
import {
listdept,
save,
del
del,
updateStatus
} from "../../api/system/department.js";
import {
listuser
@ -110,7 +120,8 @@
leader: "",
sortnumber: 0,
icon: "",
pname: "上级部门"
pname: "上级部门",
status: 1 // 1-0-
},
rules: {
name: [{
@ -239,6 +250,31 @@
});
}
},
//
toggleStatus(row) {
const newStatus = row.status === 1 ? 0 : 1;
const actionText = newStatus === 1 ? '启用' : '禁用';
this.$confirm(`确认要${actionText}该部门?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: newStatus === 1 ? 'success' : 'warning',
center: true
}).then(() => {
const params = {
id: row.id,
status: newStatus
};
save(params).then(response => {
this.$message.success('操作成功');
this.load();
}).catch(error => {
this.$message.error('操作失败');
});
}).catch(() => {
//
});
},
}
};
</script>

Loading…
Cancel
Save