[update] 市场法规清单

This commit is contained in:
lideqin
2024-06-20 17:11:52 +08:00
parent 6a6ce2db9c
commit 143a1edf7a
8 changed files with 599 additions and 37 deletions
+19 -1
View File
@@ -134,6 +134,17 @@ const addStandardMasterPlan = (params) => postAction('/laws/StandardMasterPlan/a
// 标准主计划-编辑
const editStandardMasterPlan = (params) => postAction('/laws/StandardMasterPlan/edit', params)
// 市场法规清单-根据id查询-用于编辑
const getMarketRegulationListById = (params) => getAction('', params)
// 市场法规清单-根据ids获取多个清单的清单列表-用于复制
const getMarketRegulationListByIds = (params) => getAction('', params)
// 市场法规清单-新增
const marketRegulationListAdd = (params) => postAction('', params)
// 市场法规清单-编辑
const marketRegulationListEdit = (params) => postAction('', params)
// 市场法规清单-获取历史版本列表
const marketRegulationListHistoryList = (params) => getAction('', params)
export {
// 国内标准
getDomesticStandardSearchForm,
@@ -209,5 +220,12 @@ export {
// 标准主计划
getStandardMasterPlanById,
addStandardMasterPlan,
editStandardMasterPlan
editStandardMasterPlan,
// 市场法规清单
getMarketRegulationListById,
getMarketRegulationListByIds,
marketRegulationListAdd,
marketRegulationListEdit,
marketRegulationListHistoryList
}
@@ -74,7 +74,8 @@ module.exports = {
customName: '自定义名称',
securityClass: '密级',
listDeclaration: '清单说明',
templateName: '市场法规清单导入模版'
templateName: '市场法规清单导入模版',
historicalVersion: '历史版本'
},
// 市场清单详情列表字段
marketListField: {
+1
View File
@@ -197,6 +197,7 @@ module.exports = {
clauseNo: '条款号',
clauseName: '条款名称',
clauseContent: '条款内容',
maximumSelectFive: '最多选择五条记录!',
// 标准字段
standardField: {
standardEnglishName: '标准英文名称',
@@ -94,12 +94,6 @@
</a-tooltip>
</template>
<template v-slot:action="{text, record}">
<a @click="handleEdit(record)">{{ $t('edit') }}</a>
<a-divider type="vertical" />
<a @click="handleDelete(record.id)" class="table-ope-btn">{{ $t('delete') }}</a>
</template>
</j-table>
</div>
<!-- table区域-end -->
@@ -111,10 +105,12 @@
import InternalDetailPage from '../../../components/InternalDetailPage'
import FileEcho from '../../../components/FileEcho'
import { JeroListMixin } from '../../../mixins/JeroListMixin'
import { getMarketRegulationListById } from '../../../api/standardRegulationLibraryApi'
import JTable from '../../../components/jero/JTable'
export default {
name: 'MarketRegulationsDetailPage',
components: { InternalDetailPage, FileEcho },
components: { InternalDetailPage, FileEcho, JTable },
mixins: [JeroListMixin],
data () {
return {
@@ -270,12 +266,44 @@ export default {
fixed: 'right',
width: 170
}
]
],
disableMixinCreated: true
}
},
mounted () {
if (this.$route.query.ids) {
this.filters.ids = this.$route.query.ids
}
if (this.$route.query.versionNumber) {
this.filters.versionNumber = this.$route.query.versionNumber
}
this.initData()
},
methods: {
initData (id) {
this.loading = true
getMarketRegulationListById({ id }).then(res => {
if (res.success) {
this.model = Object.assign({}, res.result)
this.dataSource = JSON.parse(JSON.stringify(this.model.data))
this.dataList = JSON.parse(JSON.stringify(this.model.data))
}
}).finally(() => {
this.loading = false
})
},
toDetail (record) {
}
}
}
</script>
<style scoped>
<style scoped lang="less">
.content-wrapper {
height: calc(100% - 52px);
box-sizing: border-box;
overflow: auto;
padding: 32px 20px;
}
</style>
@@ -1,5 +1,10 @@
<template>
<internal-detail-page :title="$route.query.title" :content-padding="0" :loading="loading">
<!-- 标题右侧按钮 -->
<template v-if="model.id" v-slot:titleRightCustom>
<!-- 历史版本 -->
<a-button type="primary" ghost @click="clickHistoryVersion">{{ $t('standardRegulationLibrary.marketRegulationsList.historicalVersion') }}</a-button>
</template>
<div class="content-wrapper">
<a-form :form="form">
<a-row>
@@ -140,7 +145,7 @@
:can-drag="true"
:scroll="{x: '100%', y: yScrollHeight}"
ref="table"
rowKey="id"
rowKey="uid"
:columns="columns"
:dataSource="dataSource"
:pagination="false"
@@ -159,7 +164,7 @@
<template v-slot:action="{text, record}">
<a @click="handleEdit(record)">{{ $t('edit') }}</a>
<a-divider type="vertical" />
<a @click="handleDelete(record.id)" class="table-ope-btn">{{ $t('delete') }}</a>
<a @click="handleDelete(record.uid)" class="table-ope-btn">{{ $t('delete') }}</a>
</template>
</j-table>
@@ -178,29 +183,85 @@
<!-- 新增编辑弹框 -->
<market-regulations-modal ref="marketRegulationsModal" @ok="modalFormOk"/>
<!-- 调取弹框 -->
<standard-selection-modal ref="transferModal" @ok="transferOk"/>
<standard-selection-modal :canSelectedSource="[StandardSource.FOREIGN.value]"
:disabledSourceSearch="true"
ref="transferModal"
@listChange="transferOk"/>
<!-- 复制弹框 -->
<market-regulations-list-selection-modal ref="copyModal" @ok="copyOk"/>
<market-regulations-list-selection-modal ref="copyModal" @change="copyOk"/>
<!-- 历史版本弹框 -->
<history-version-modal ref="historyVersionModal"/>
</internal-detail-page>
</template>
<script>
import InternalDetailPage from '@/components/InternalDetailPage'
import JTable from '@/components/jero/JTable'
import { JeroListMixin } from '../../../mixins/JeroListMixin'
import MarketRegulationsModal from './modules/MarketRegulationsModal'
import StandardSelectionModal from '../../../components/selection/StandardSelectionModal'
import MarketRegulationsListSelectionModal from '../../../components/selection/MarketRegulationsListSelectionModal'
import {
getMarketRegulationListById,
getMarketRegulationListByIds,
marketRegulationListAdd,
marketRegulationListEdit
} from '../../../api/standardRegulationLibraryApi'
import pick from 'lodash.pick'
import { StandardSource } from '../../../enums/commonEnums'
import { mapGetters } from 'vuex'
import Vue from 'vue'
import { ACCESS_TOKEN, TENANT_ID } from '../../../store/mutation-types'
import { downloadFile } from '../../../api/manage'
import HistoryVersionModal from './modules/HistoryVersionModal'
const uidGenerator = () => {
return '-' + parseInt(Math.random() * 10000 + 1, 10)
}
// 导入的加载提示
let importModalLoading
export default {
name: 'MarketRegulationsFormPage',
components: { MarketRegulationsListSelectionModal, StandardSelectionModal, InternalDetailPage, JTable, MarketRegulationsModal },
mixins: [JeroListMixin],
components: {
MarketRegulationsListSelectionModal,
StandardSelectionModal,
InternalDetailPage,
JTable,
MarketRegulationsModal,
HistoryVersionModal
},
computed: {
...mapGetters(['defaultHeight']),
yScrollHeight () {
/**
* 前几个使用变量是为了配合iframe嵌套,算出页面显示范围的高度
* 48px:分页器的高度
* 48pxa-card的padding(上24+下24
* 54px:表头行的高度
*/
return `calc(100vh - ${this.defaultHeight['user-info-height']} - ${this.defaultHeight['breadcrumb-height']} - ${this.defaultHeight.oneLineSearchHeight} - ${this.defaultHeight.oneLineOperationHeight} - 48px - 48px - 54px - ${this.isBackTitle ? '56px' : '0px'})`
},
// token header
tokenHeader () {
const head = { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) }
const tenantid = Vue.ls.get(TENANT_ID)
if (tenantid) {
head['tenant-id'] = tenantid
}
return head
},
importExcelUrl: function () {
return `${window._CONFIG.domianURL}/${this.url.importExcelUrl}`
}
},
data () {
return {
StandardSource,
loading: false,
form: this.$form.createForm(this),
model: {},
queryParam: {},
labelCol: {
xs: { span: 24 },
sm: { span: 4 }
@@ -395,20 +456,226 @@ export default {
width: 170
}
],
dataSource: [],
dataList: [], // 用于查询的数据,保证查询后数据不变
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
selectedRowKeys: [],
selectionRows: [],
showList: false, // 是否展示清单
url: {
importExcelUrl: ''
},
disableMixinCreated: true
importExcelUrl: '',
downTemplateUrl: ''
}
}
},
mounted () {
if (this.$route.query.id) {
this.initData(this.$route.query.id)
}
},
methods: {
initData (id) {
this.loading = true
getMarketRegulationListById({ id }).then(res => {
if (res.success) {
this.model = Object.assign({}, res.result)
this.dataSource = JSON.parse(JSON.stringify(this.model.data.map(item => {
return { ...item, uid: uidGenerator() }
})))
this.dataList = JSON.parse(JSON.stringify(this.model.data.map(item => {
return { ...item, uid: uidGenerator() }
})))
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'countryRegion', 'listNumber', 'customName', 'drivingPosition', 'securityClass', 'listDeclaration', 'attach'))
})
}
}).finally(() => {
this.loading = false
})
},
// 点击历史版本
clickHistoryVersion () {
this.$refs.historyVersionModal.open(this.model.id)
},
// 查询
searchQuery () {
if (this.queryParam.standardNumber && this.queryParam.standardName) {
this.dataSource = this.dataList.filter(item => {
return item.standardNumber.indexOf(this.queryParam.standardNumber) && item.standardName.indexOf(this.queryParam.standardName)
})
} else if (this.queryParam.standardNumber) {
this.dataSource = this.dataList.filter(item => {
return item.standardNumber.indexOf(this.queryParam.standardNumber)
})
} else if (this.queryParam.standardName) {
this.dataSource = this.dataList.filter(item => {
return item.standardName.indexOf(this.queryParam.standardName)
})
} else {
this.dataSource = JSON.parse(JSON.stringify(this.dataList))
}
this.selectedRowKeys = []
this.selectionRows = []
},
// 重置
searchReset () {
this.queryParam = {}
this.dataSource = JSON.parse(JSON.stringify(this.dataList))
this.selectedRowKeys = []
this.selectionRows = []
},
onSelectChange (selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys
this.selectionRows = selectionRows
},
handleTableChange (pagination, filters, sorter) {
// 分页、排序、筛选变化时触发
this.ipagination = pagination
},
batchDel () {
if (this.selectedRowKeys.length <= 0) {
this.$message.warning(this.$t('selectARecord'))
} else {
this.$confirm({
title: this.$t('confirmBatchDeletion'),
content: this.$t('deleteAData'),
onOk: () => {
this.loading = true
this.dataList.filter(item => !this.selectedRowKeys.includes(item.uid))
this.dataSource.filter(item => !this.selectedRowKeys.includes(item.uid))
this.reCalculatePage(this.selectedRowKeys.length)
this.onClearSelected()
this.loading = false
}
})
}
},
/* 导入 */
handleImportExcel (info) {
// 限制导入大于500MB
if (info.file.size > 1024 * 1024 * 500) {
this.$message.error('导入文件最大500MB')
info.fileList.pop()
return
}
// 加一个大的提示
if (!this.loading) {
importModalLoading = this.$info({
title: '提示',
content: <span>正在导入请稍候 <a-spin size="small" /></span>,
keyboard: false
})
}
this.loading = true
// 把知道了这个按钮去掉
this.$nextTick(() => {
document.getElementsByClassName('ant-modal-confirm-btns')[0].style = 'display:none'
})
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList)
}
if (info.file.status === 'done') {
// 销毁这个提示
importModalLoading && importModalLoading.destroy()
this.loading = false
if (info.file.response.success) {
// this.$message.success(`${info.file.name} 文件上传成功`);
if (info.file.response.code === 201) {
const { message, result: { msg, fileUrl, fileName } } = info.file.response
const href = window._CONFIG.domianURL + fileUrl
this.$warning({
title: message,
content: (<div>
<span>{msg}</span><br />
<span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
</div>
)
})
} else {
this.$message.success(info.file.response.message || `${info.file.name} 文件上传成功`)
}
// 推入表格中
this.dataSource = info.file.response.result.map(item => {
return { uid: uidGenerator(), ...item }
})
this.dataList = info.file.response.result.map(item => {
return { uid: uidGenerator(), ...item }
})
} else {
if (Array.isArray(info.file.response.result) && info.file.response.result.length > 0) {
this.messageLineFeed(this.$t('fileImportError'), info.file.response.result)
} else if (/<br>|<\/br>|<br\/>/.test(info.file.response.message)) {
this.messageLineFeedByBr(this.$t('fileImportError'), info.file.response.message)
} else {
this.$message.warning(`${info.file.name} ${info.file.response.message}`)
}
}
} else if (info.file.status === 'error') {
// 销毁这个提示
importModalLoading && importModalLoading.destroy()
this.loading = false
if (info.file.response.status === 500) {
const data = info.file.response
const token = Vue.ls.get(ACCESS_TOKEN)
if (token && data.message.includes('Token失效')) {
this.error({
title: '登录已过期',
content: '很抱歉,登录已过期,请重新登录',
okText: '重新登录',
mask: false,
onOk: () => {
store.dispatch('Logout').then(() => {
Vue.ls.remove(ACCESS_TOKEN)
window.location.reload()
})
}
})
}
} else {
this.$message.warning(`文件上传失败: ${info.file.msg} `)
}
}
},
// 下载导入模板
downTemplate (fileName, fileSuffix = '.xls') {
if (!fileName || typeof fileName !== 'string') {
fileName = '模板文件'
}
downloadFile(this.url.downTemplateUrl, fileName + fileSuffix)
},
onClearSelected () {
this.selectedRowKeys = []
this.selectionRows = []
},
reCalculatePage (count) {
// 总数量-count
const total = this.ipagination.total - count
// 获取删除后的分页数
const currentIndex = Math.ceil(total / this.ipagination.pageSize)
// 删除后的分页数<所在当前页
if (currentIndex < this.ipagination.current) {
this.ipagination.current = currentIndex
}
console.log('currentIndex', currentIndex)
},
// 下一步
handleNext () {
this.showList = true
},
// 新增
handleAdd () {
this.$refs.marketRegulationsModal.title = this.$t('newlyAdded')
this.$refs.marketRegulationsModal.add()
},
// 调取
@@ -421,23 +688,101 @@ export default {
},
// 新增完成
modalFormOk (value) {
this.dataSource.unshift(value)
if (!value.uid) {
// 是新增完成
this.dataSource.unshift({ ...value, uid: uidGenerator() })
this.dataList.unshift({ ...value, uid: uidGenerator() })
} else {
// 是编辑完成
const index = this.dataSource.findIndex(item => item.uid === value.uid)
this.dataSource.splice(index, 1, value)
const listIndex = this.dataList.findIndex(item => item.uid === value.uid)
this.dataList.splice(listIndex, 1, value)
}
},
// 调取完成
transferOk (list) {
// 已经有的标准去掉,调取不重复的
for (const item of list) {
if (!this.dataList.includes(i => i.standardNumber === item.standardNumber)) {
// 列表中还没有该标准
this.dataSource.unshift({ ...item, uid: uidGenerator() })
this.dataList.unshift({ ...item, uid: uidGenerator() })
}
}
},
// 复制完成
copyOk (ids) {
// 根据选中的清单,获取清单列表,并且表格中不存在的添加到表格中
getMarketRegulationListByIds({ ids }).then(res => {
if (res.success) {
for (const item of res.result) {
if (!this.dataList.includes(i => i.standardNumber === item.standardNumber)) {
// 列表中还没有该标准
this.dataSource.unshift({ ...item, uid: uidGenerator() })
this.dataList.unshift({ ...item, uid: uidGenerator() })
}
}
}
})
},
// 编辑
handleEdit (record) {
this.$refs.marketRegulationsModal.title = this.$t('edit')
this.$refs.marketRegulationsModal.edit(record)
},
// 删除
handleDelete (uid) {
this.$confirm({
title: this.$t('confirmDeletion'),
content: this.$t('areYouSure'),
onOk: function () {
// 判断当前删除的数据是否是最后一页的最后一条数据,如果是的话页码减一
if (this.ipagination.current > 1 && ((this.ipagination.current - 1) * this.ipagination.pageSize) + 1 === this.ipagination.total) {
this.ipagination.current -= 1
}
this.dataList.filter(item => item.uid !== uid)
this.dataSource.filter(item => item.uid !== uid)
}
})
},
// 取消
handleCancel () {
},
// 调取完成
transferOk () {
},
// 复制完成
copyOk () {
this.close()
},
// 提交
handleSubmit () {
if (this.loading) return
this.form.validateFields((err, values) => {
if (!err) {
this.loading = true
const param = Object.assign({}, values)
let func
if (this.model.id) {
param.id = this.model.id
func = marketRegulationListEdit
} else {
func = marketRegulationListAdd
}
param.dataList = this.dataList
func(param).then(res => {
if (res.success) {
this.$message.success(res.message)
this.$emit('ok')
this.close()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.confirmLoading = false
})
}
})
},
close () {
this.model = {}
this.dataSource = []
this.dataList = []
}
}
}
@@ -229,13 +229,38 @@ export default {
}
})
},
// 编辑
handleEdit (record) {
this.$router.push({
path: '/standardRegulationLibrary/marketRegulationsList/marketRegulationsFormPage',
query: {
title: this.$t('edit'),
id: record.id
}
})
},
// 批量发布
handleBatchPublish () {
},
// 查看
handleLook () {
if (this.selectedRowKeys.length <= 0) {
// 至少选择一条数据
this.$message.warning(this.$t('selectARecord'))
return
} else if (this.selectedRowKeys.length > 5) {
// 最多选择五条数据
this.$message.warning(this.$t('maximumSelectFive'))
return
}
this.$router.push({
path: '/standardRegulationLibrary/marketRegulationsList/marketRegulationsDetailPage',
query: {
title: this.$t('view'),
ids: this.selectedRowKeys.join(',')
}
})
},
// 发布
handlePublish () {
@@ -0,0 +1,94 @@
<template>
<j-modal
:title="title"
:maskClosable="true"
:width="400"
:closable="true"
switchFullscreen
:footer="false"
@cancel="handleCancel"
:visible="visible">
<a-table
ref="table"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:loading="loading"
:showHeader="false"
:scroll="{x: '100%', y: 'calc(100vh - 500px)'}">
<template v-slot:toDetail="text, record">
<a-tooltip overlay-class-name="tooltip-style">
<template slot="title">{{ text || text === 0 ? text : global.emptyLine }}</template>
<a v-if="text" class="link-a" @click="handleGoDetail(record)">{{ text }}</a>
<div v-else class="table-text">{{ global.emptyLine }}</div>
</a-tooltip>
</template>
</a-table>
</j-modal>
</template>
<script>
import { marketRegulationListHistoryList } from '../../../../api/standardRegulationLibraryApi'
export default {
name: 'HistoryVersionModal',
data () {
return {
title: this.$t('standardRegulationLibrary.marketRegulationsList.historicalVersion'),
visible: false,
loading: false,
model: {},
columns: [
{
align: 'center',
width: 180,
dataIndex: 'version',
scopedSlots: { customRender: 'toDetail' }
}
],
dataSource: [
{id: 1, version: 'V1.0'},
{id: 2, version: 'V2.0'},
{id: 3, version: 'V3.0'},
]
}
},
methods: {
open (id) {
this.visible = true
this.model.id = id
// this.initData(id)
},
initData (id) {
marketRegulationListHistoryList({ id }).then(res => {
if (res.success) {
this.dataSource = res.result
}
})
},
// 点击版本号
handleGoDetail (record) {
this.$router.push({
path: '/standardRegulationLibrary/marketRegulationsList/marketRegulationsDetailPage',
query: {
title: this.$t('view'),
ids: this.model.id,
versionNumber: record.version
}
})
},
handleCancel () {
this.visible = false
this.dataSource = []
}
}
}
</script>
<style scoped>
</style>
@@ -17,7 +17,8 @@
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('standardNumber')">
<standard-selection :placeholder="$t('pleaseSelect') + $t('standardNumber')"
type="radio"
v-decorator.trim="[ 'standardId', validatorRules.standardId ]" />
@listChange="selectStandardChange"
v-decorator.trim="[ 'standardNumber', validatorRules.standardNumber ]" />
</a-form-item>
<!-- 标准名称 -->
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" :label="$t('standardName')">
@@ -141,6 +142,8 @@
<script>
import StandardSelection from '@/components/selection/StandardSelection'
import JMultipleDatePicker from '../../../../components/JMultipleDatePicker'
import pick from 'lodash.pick'
import { getForeignStandardDocumentInfo } from '../../../../api/standardRegulationLibraryApi'
export default {
name: 'MarketRegulationsModal',
@@ -163,7 +166,7 @@ export default {
},
validatorRules: {
// 标准编号
standardId: {
standardNumber: {
rules: [{
required: true,
message: this.$t('pleaseSelect') + this.$t('standardNumber')
@@ -255,10 +258,57 @@ export default {
},
methods: {
add () {
this.edit({})
},
edit (record) {
this.form.resetFields()
this.visible = true
this.model = Object.assign({}, record)
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'standardNumber', 'standardName', 'standardEnglishName',
'type', 'newProductionVehicleImplementationDate', 'newCertifiedVehicleImplementationDate',
'dateOfRegistration', 'applicableCountryRegion', 'authenticationObject', 'certifiedDeliverables',
'mainControlDepartment', 'masterControlDepartmentProfessionalModule', 'relatedDepartment',
'associateDepartmentSpecializedModules', 'applicableVehicleType', 'dynamicType', 'batchRestriction',
'automaticDrivingLevel', 'requirementType'))
})
},
// 选择标准改变
selectStandardChange (value) {
this.loading = true
// 企标名称
this.formInline.standardName = value[0].standardName
// 根据返回的id查询企标数据
getForeignStandardDocumentInfo({ id: value[0].id, type: '2' }).then(res => {
if (res.success) {
const result = res.result
this.$nextTick(() => {
this.form.setFieldsValue(pick(result, 'standardNumber', 'standardName', 'standardEnglishName',
'type', 'newProductionVehicleImplementationDate', 'newCertifiedVehicleImplementationDate',
'dateOfRegistration', 'applicableCountryRegion', 'authenticationObject', 'certifiedDeliverables',
'mainControlDepartment', 'masterControlDepartmentProfessionalModule', 'relatedDepartment',
'associateDepartmentSpecializedModules', 'applicableVehicleType', 'dynamicType', 'batchRestriction',
'automaticDrivingLevel', 'requirementType'))
})
}
}).finally(() => {
this.loading = false
})
},
handleOk () {
if (this.confirmLoading) return
this.form.validateFields((err, values) => {
if (!err) {
this.confirmLoading = true
const param = Object.assign({}, values)
if (this.model.uid) {
this.$emit('ok', { ...this.model, ...param })
} else {
this.$emit('ok', param)
}
this.confirmLoading = false
}
})
},
handleCancel () {
this.close()