Compare commits

...

2 Commits
master ... dev

Author SHA1 Message Date
zhouhaibin 835a016783 造价管理前端 4 months ago
zhouhaibin 4c89d00851 产品管理初步代码提交 4 months ago
  1. 2
      .eslintrc.js
  2. 1
      package.json
  3. 6
      src/api/index.ts
  4. 13
      src/main.ts
  5. 236
      src/mixin/referenceMixin_copy.js
  6. 117
      src/modules/costManagement/api/index.ts
  7. 222
      src/modules/costManagement/components/costTypeComponents.vue
  8. 49
      src/modules/costManagement/view/costIndex/index.vue
  9. 368
      src/modules/costManagement/view/costTable/add.vue
  10. 194
      src/modules/costManagement/view/costTable/index.vue
  11. 376
      src/modules/costManagement/view/costTable/modify.vue
  12. 221
      src/modules/costManagement/view/costTable/view.vue
  13. 126
      src/modules/productManagement/api/index.ts
  14. 251
      src/modules/productManagement/components/productModelComponents.vue
  15. 141
      src/modules/productManagement/components/productModelSelectComponents.vue
  16. 220
      src/modules/productManagement/components/productModelTemplateComponents.vue
  17. 145
      src/modules/productManagement/components/supplierInformationComponents.vue
  18. 209
      src/modules/productManagement/view/companyProducts/index.vue
  19. 208
      src/modules/productManagement/view/personProducts/index.vue
  20. 167
      src/modules/productManagement/view/productModelTemplate/index.vue
  21. 69
      src/modules/productManagement/view/supplierInformation/add.vue
  22. 148
      src/modules/productManagement/view/supplierInformation/index.vue
  23. 69
      src/modules/productManagement/view/supplierInformation/modify.vue
  24. 55
      src/modules/productManagement/view/supplierInformation/view.vue
  25. 220
      src/modules/productManagement/view/supplierProducts/index.vue
  26. 2
      src/views/Login/components/LoginForm.vue
  27. 2
      vite.config.ts

2
.eslintrc.js

@ -42,7 +42,7 @@ module.exports = defineConfig({
'no-unused-vars': 'off',
"vue/no-unused-components": "off",
'space-before-function-paren': 'off',
'prettier/prettier': 'off',
'vue/attributes-order': 'off',
'vue/one-component-per-file': 'off',
'vue/html-closing-bracket-newline': 'off',

1
package.json

@ -32,6 +32,7 @@
"@form-create/element-ui": "^3.1.24",
"@iconify/iconify": "^3.1.0",
"@iconify/vue": "^4.1.1",
"@smallwei/avue": "^3.4.2",
"@vueuse/core": "^9.13.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.10",

6
src/api/index.ts

@ -6,6 +6,8 @@ import * as scheduler from '@/modules/scheduler/api'
import * as notification from '@/modules/notification/api'
import * as workflow from '@/modules/workflow/api'
import * as businessflow from '@/modules/businessflow/api'
import * as productManagement from '@/modules/productManagement/api'
import * as costManagement from '@/modules/costManagement/api'
export default {
system,
@ -15,5 +17,7 @@ export default {
scheduler,
notification,
workflow,
businessflow
businessflow,
productManagement,
costManagement
}

13
src/main.ts

@ -28,7 +28,9 @@ import { setupRouter } from './router'
import { setupPermission } from './directives'
import { createApp } from 'vue'
//新增第三方组件
import Avue from '@smallwei/avue';
import '@smallwei/avue/lib/index.css';
import App from './App.vue'
import './permission'
@ -109,7 +111,14 @@ const setupAll = async () => {
// 全量注册element-plus组件
app.use(ElementPlus)
// 全量注册avue组件
app.use(Avue,{
crudOption:{
index: true, //是否展示序号列
indexLabel: '序号', //序号列名称
indexWidth: 60, //序号列宽度
}
});
// 自定义表单
app.use(FormCreate)
app.use(FcDesigner)

236
src/mixin/referenceMixin_copy.js

@ -0,0 +1,236 @@
/**
* 参照页面混入
*/
import { Dialog } from '@/components/abc/Dialog'
import CollapseTab from '@/components/abc/CollapseTab/index.vue'
import QueryText from '@/components/abc/QueryText/index.vue'
import QueryButton from '@/components/abc/QueryButton/index.vue'
import { ContentWrap } from '@/components/abc/ContentWrap'
import ListPager from '@/components/abc/ListPager/index.vue'
import ColumnsController from '@/components/abc/ColumnsController/index.vue'
import DictionarySelect from '@/components/abc/DictionarySelect/DictionarySelect.vue'
import DictionaryRadioGroup from '@/components/abc/DictionarySelect/DictionaryRadioGroup.vue'
import OrganizationSingleSelect from '@/modules/system/view/organization/treeReference.vue'
import OrganizationMultipleSelect from '@/modules/system/view/organization/treeMultipleSelect.vue'
import UserSingleSelect from '@/modules/system/view/user/treeListReference.vue'
import IconPicker from '@/components/abc/IconPicker/index.vue'
export const referenceMixin_copy = {
emits: ['update:modelValue', 'my-change'],
components: {
Dialog,
ContentWrap,
CollapseTab,
QueryText,
QueryButton,
ListPager,
ColumnsController,
DictionarySelect,
DictionaryRadioGroup,
OrganizationSingleSelect,
OrganizationMultipleSelect,
UserSingleSelect,
IconPicker
},
props: {
modelValue: {
type: String,
default: '',
required: false
},
disabled: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
// 表格数据
tableData: [],
// 加载中
loading: false,
// 当前行
currentId: this.$constant.NO_ITEM_SELECTED,
// 分页信息
pageInfo: {
// 页码
pageNum: this.$constant.DEFAULT_PAGE_NUM,
// 页码大小
pageSize: this.$constant.DEFAULT_PAGE_SIZE
},
// 排序信息
sortInfo: {
sort_field: 'orderNo',
sort_sortType: 'ascending'
},
// 总页数
pageTotal: 0,
queryCondition: {
// 默认值处理
},
visible: false,
// 显示名称
displayName: ''
}
},
watch: {
modelValue: {
immediate: true,
handler: 'getSelectedName'
}
},
computed: {
showCols() {
return this.columnList.filter((item) => item.show)
},
tableKey() {
const { path } = this.$route
return `${path}/table`
}
},
methods: {
// 初始化
init(param) {
if (this.beforeInit != null) {
this.beforeInit(param)
}
this.loadData().then((res) => {
if (this.afterInit) {
this.afterInit(param)
}
this.visible = true
})
},
// 确认选择
confirm() {
if (!this.checkSelectedRowExist()) {
return
}
const selectedRow = this.getRow(this.currentId)
this.displayName = selectedRow.name
// 更新父组件绑定值
this.$emit('update:modelValue', selectedRow.id)
this.$emit('my-change', selectedRow.id, selectedRow)
this.visible = false
if (this.afterConfirm!=null) {
this.afterConfirm(selectedRow)
}
},
// 关闭
close() {
this.visible = false
},
// 清空选择
clear() {
this.displayName = ''
this.$emit('update:modelValue', '')
this.$emit('my-change', '')
},
// 获取选中的名称
getSelectedName() {
if (this.modelValue) {
this.api.get(this.modelValue).then((res) => {
this.displayName = res.data[this.nameKey]
})
}
},
// 加载数据
loadData() {
return new Promise((resolve) => {
this.loading = true
const params = Object.assign(this.queryCondition, this.pageInfo, this.sortInfo)
this.api
.page(params)
.then((res) => {
this.tableData = res.data.records
this.pageTotal = res.data.total
resolve()
})
.finally(() => {
this.loading = false
this.currentId = this.$constant.NO_ITEM_SELECTED
})
})
},
// 查看
view(id) {
if (this.$refs.viewPage) {
this.$refs.viewPage.init(id)
}
},
// 刷新
refresh() {
this.loadData()
},
// 处理排序
// eslint-disable-next-line no-unused-vars
sortChange({ column, prop, order }) {
this.sortInfo.sort_field = prop
this.sortInfo.sort_sortType = order
this.refresh()
},
// 当前行变化
rowChange(currentRow) {
this.currentId = currentRow ? currentRow.id : this.$constant.NO_ITEM_SELECTED
},
// 获取行记录
getRow(id) {
if (id && id !== this.$constant.NO_ITEM_SELECTED) {
if (this.tableData && this.tableData.length > 0) {
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i].id === id) {
return this.tableData[i]
}
}
}
}
return undefined
},
// 获取名称
getName(id) {
const row = this.getRow(id)
if (row) {
return row[this.nameKey]
}
return undefined
},
// 验证是否有选中行
checkSelectedRowExist() {
if (this.currentId === this.$constant.NO_ITEM_SELECTED) {
this.$message.info('当前无选中行')
return false
}
return true
},
// 双击事件
rowDoubleClick(row) {
this.view(row.id)
},
// 处理查询
query() {
// 查询之前,将当前页置为1
this.pageInfo.pageNum = 1
this.refresh()
},
// 处理分页变化
pageChange(value) {
this.pageInfo.pageNum = value
this.refresh()
},
// 处理分页大小变化
pageSizeChange(value) {
this.pageInfo.pageSize = value
this.refresh()
}
},
provide() {
return {
query: this.query,
view: this.view,
pageChange: this.pageChange,
pageSizeChange: this.pageSizeChange
}
}
}

117
src/modules/costManagement/api/index.ts

@ -0,0 +1,117 @@
import { COMMON_METHOD } from '@/constant/common'
import request from '@/config/axios'
const moduleName = 'costManagement'
// 系统参数
// export const param = Object.assign({}, COMMON_METHOD, {
// serveUrl: '/' + moduleName + '/' + 'param' + '/'
// })
// 供应商管理
// export const supplierInformation = {
// serveUrl: '/' + moduleName + '/' + 'supplierInformation' + '/',
// page(params) {
// return request.get({ url: this.serveUrl + 'page', params })
// },
// get(id) {
// return request.get({ url: this.serveUrl + id })
// }
// }
// 造价表
export const costTable = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'costTable' + '/',
// 新增
addCostTable(itemList) {
return request.post({ url: this.serveUrl + 'addCostTable', data: itemList })
},
// 查询数据
getCostTableDetail(id) {
return request.get({ url: this.serveUrl + 'getCostTableDetail/' + id })
},
modifyCostTable(params){
return request.put({ url: this.serveUrl + 'modifyCostTable', data: params })
}
})
// 造价明细
export const costItemDetail = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'costItemDetail' + '/',
// 全产品造价
getProductsPageByType(params) {
return request.get({ url: this.serveUrl + 'getProductsPageByType', params })
},
// 查询数据
getCostTableDetail(id) {
return request.get({ url: this.serveUrl + 'getCostTableDetail/' + id })
},
modifyCostTable(params){
return request.put({ url: this.serveUrl + 'modifyCostTable', data: params })
}
})
// 字典类型
export const dictionaryType = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'dictionaryType' + '/',
tree() {
return request.get({ url: this.serveUrl + 'tree' })
},
// 通过编码获取数据
getByCode(param) {
return request.get({ url: this.serveUrl + 'getByCode/' + param })
},
// 批量保存
saveItem(id, itemList) {
return request.post({ url: this.serveUrl + id + '/item', data: itemList })
},
// 通过编码获取字典项,转换为列表项数据结构,用于公用选择控件
getItem(code) {
return request.get({ url: this.serveUrl + 'getItem?code=' + code })
}
})
// 字典项
export const dictionaryItem = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'dictionaryItem' + '/',
enable(id) {
return request.put({ url: this.serveUrl + id + '/enable' })
},
disable(id) {
return request.put({ url: this.serveUrl + id + '/disable' })
}
})
// 用户设置
export const userProfile = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'userProfile' + '/',
get() {
return request.get({ url: this.serveUrl })
}
})
// 系统管理
export const systemManage = Object.assign(
{},
{
serveUrl: '/' + moduleName + '/' + 'systemManage' + '/',
// 重建系统缓存
rebuildSystemCache() {
return request.put({ url: this.serveUrl + 'rebuildSystemCache' })
},
// 获取唯一性标识
getUniqueId() {
// 获取唯一性标识
return request.get({ url: this.serveUrl + 'getUniqueId' })
}
}
)
// 模块
export const module = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'module' + '/'
})

222
src/modules/costManagement/components/costTypeComponents.vue

@ -0,0 +1,222 @@
<template>
<div class="w-full">
<el-input v-model="displayName" disabled style="width: 152px" />
<el-button-group>
<el-button icon="grid" @click="init" style="border-left-width: 0; padding: 10px" />
<el-button icon="delete" @click="clear" style="border-left-width: 0; padding: 10px" />
</el-button-group>
<Dialog title="模块选择" v-model="visible" width="80%">
<el-container>
<el-aside width="200px">
<avue-tree ref="treeRef" :option="treeOption" :data="treeData" @node-click="nodeClick" />
</el-aside>
<el-main>
<avue-crud
v-model:page="page"
v-model:search="queryCondition"
@search-change="searchChange"
@current-row-change="handleCurrentRowChange"
@row-dblclick="confirm"
@on-load="onLoad"
:data="loadData"
:option="loadOption"
>
<template #menu-left="{}">
<el-button
type="danger"
icon="el-icon-plus"
@click="addrow()"
v-permission="'productManagement:personProducts:add'"
>新增个人产品</el-button
>
</template>
</avue-crud>
</el-main>
</el-container>
<template #footer>
<el-button type="primary" @click="confirm">确定</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</div>
</template>
<script>
import { Dialog } from '@/components/abc/Dialog'
const MODULE_CODE = 'costManagement'
const ENTITY_TYPE = 'costItemDetail'
export default {
emits: ['update:modelValue', 'updateCostInfo', 'my-change'],
name: ENTITY_TYPE + '-reference',
components: { Dialog },
mixins: [],
props: {
moduleParam: {
type: Object,
required: false
},
modelValue: {
type: String,
required: false
},
costDescribe: {
type: String,
required: false
}
},
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
visible: false,
queryCondition: {},
currentRow: {},
displayName: '',
page: {
total: 0,
currentPage: 1,
pageSize: 10
},
pageInfo: {
//
pageNum: 1,
//
pageSize: 10
},
sortInfo: {
sort_field: 'id',
sort_sortType: 'descending'
},
treeData: [
{
value: '全产品库',
label: '全产品库'
},
{
value: '供应商产品库',
label: '供应商产品库'
},
{
value: '公司产品库',
label: '公司产品库'
},
{
value: '个人产品库',
label: '个人产品库'
}
],
treeOption: {
defaultExpandAll: true,
filter: false
},
loadData: [],
loadOption: {
highlightCurrentRow: true,
menu: false,
addBtn: false,
labelWidth: 120,
column: {
productName: {
label: '产品名称',
labelWidth: 120,
search: true,
searchLabelWidth: 120
},
productIdentity: {
label: '产品标识(型号)',
labelWidth: 120,
search: true,
searchLabelWidth: 120
},
productPrice: {
label: '产品价格',
labelWidth: 120,
type: 'number',
precision: 2,
mim: 0
},
modelDescription: {
label: '产品描述',
labelWidth: 120,
//editDisabled: true //
display: false //
},
remarks: {
label: '备注',
labelWidth: 120
},
productType: {
label: '所在库'
}
}
},
//
nameKey: 'supplierName'
}
},
watch: {
modelValue: {
handler(newvalue, oldvalue) {
this.displayName = newvalue
},
immediate: true
}
},
methods: {
init(param) {
if (this.beforeInit != null) {
this.beforeInit(param)
}
this.visible = true
//
this.queryCondition.productType = '全产品库'
this.pageInfo.pageNum = this.page.currentPage
const params = Object.assign(this.queryCondition, this.pageInfo, this.sortInfo)
this.api.getProductsPageByType(params).then((res) => {
this.loadData = res.data.records
this.page.total = res.data.total
// res.data.total
})
this.$refs.treeRef.setCurrentKey(-1)
},
close() {
this.visible = false
},
confirm(row) {
if (row) {
this.currentRow = row
}
this.displayName = this.currentRow.productName
this.$emit('update:modelValue', this.displayName)
this.$emit('updateCostInfo', this.currentRow)
this.visible = false
},
nodeClick(data) {
this.queryCondition.productType = data.value
this.onLoad()
},
onLoad() {
this.pageInfo.pageNum = this.page.currentPage
const params = Object.assign(this.queryCondition, this.pageInfo, this.sortInfo)
this.api.getProductsPageByType(params).then((res) => {
this.loadData = res.data.records
this.page.total = res.data.total
// res.data.total
})
},
searchChange(val, done) {
this.onLoad()
done()
},
handleCurrentRowChange(val) {
this.currentRow = val
}
}
}
</script>
<style></style>

49
src/modules/costManagement/view/costIndex/index.vue

@ -0,0 +1,49 @@
<template>
<div class="container1">
<iframe
id="modle_iframe"
src="https://www.gldjc.com/"
width="100%"
height="100%"
frameborder="0"
scrolling="auto"
></iframe>
</div>
</template>
<script>
export default {
data() {
return {}
},
mounted() {
/**
* iframe-宽高自适应显示
*/
// function changeMobsfIframe() {
// const mobsf = document.getElementById('mobsf')
// const deviceWidth = document.body.clientWidth
// const deviceHeight = document.body.clientHeight
// mobsf.style.width = Number(deviceWidth) - 240 + 'px' //
// mobsf.style.height = Number(deviceHeight) - 64 + 'px' //
// }
// changeMobsfIframe()
// window.onresize = function () {
// changeMobsfIframe()
// }
}
}
</script>
<style scoped lang="less">
.container1 {
// position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
}
// #modle_iframe {
// width: 100%;
// height: 100%;
// }
</style>

368
src/modules/costManagement/view/costTable/add.vue

@ -0,0 +1,368 @@
<template>
<Dialog title="新增" v-model="visible" width="80%">
<el-form
ref="form"
:model="entityData"
:rules="rules"
label-width="120px"
label-position="right"
style="width: 90%; margin: 0px auto"
>
<!--表单区域 -->
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="entityData.projectName" />
</el-form-item>
<el-form-item label="总投资" prop="totalInvestment">
<el-input type="number" v-model="entityData.totalInvestment" disabled />
</el-form-item>
</el-form>
<!--表格区域-->
<avue-crud
ref="crudRef"
v-model="curdForm"
v-model:defaults="defaults"
:option="option"
:data="tableData"
@row-update="addUpdate"
@row-save="rowSave"
@row-del="rowDelete"
>
<template #orderNo="{ row }">
<el-tag type="success">{{ row.orderNo }}</el-tag>
</template>
<template #menu-left="{}">
<el-button
type="danger"
icon="el-icon-plus"
@click="addrow()"
v-permission="pageCode + 'add'"
>新增</el-button
>
</template>
<template #menu="{ row, index }">
<el-button text type="primary" @click="addChild(row, index)" v-if="row.isDetail == '0'"
>增加子项</el-button
>
</template>
<template #costName-form="{}">
<costTypeComponents v-model="curdForm.costName" :module-param="moduleParam" @updateCostInfo="updateCostInfo"/>
</template>
</avue-crud>
<template #footer>
<el-button type="primary" @click="save" v-permission="pageCode + 'add'">保存</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</template>
<script>
import { addMixin } from '@/mixin/addMixin.js'
import { cloneDeep } from 'lodash-es'
import costTypeComponents from '@/modules/costManagement/components/costTypeComponents.vue'
const MODULE_CODE = 'costManagement'
const ENTITY_TYPE = 'costTable'
export default {
name: ENTITY_TYPE + '-add',
mixins: [addMixin],
components: { costTypeComponents },
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
entityData: {},
rules: {
//
projectName: [{ required: true, message: '【项目名称】不能为空', trigger: 'blur' }],
totalInvestment: [{ required: true, message: '【总投资】不能为空', trigger: 'blur' }]
},
tableData: [],
curdForm: {},
defaults: {},
parentId: undefined,
currentlevel: undefined,
currentRowData: {},
option: {
addBtn: false,
refreshBtn: false,
columnBtn: false,
gridBtn: false,
index: false,
rowKey: 'id',
rowParentKey: 'parentId',
menuWidth: 100,
column: {
orderNo: {
label: '序号',
display: false,
width: 200
},
isDetail: {
label: '是否明细',
type: 'radio',
button: true,
dicData: [
{
label: '是',
value: '1'
},
{
label: '否',
value: '0'
}
],
value: '0',
rules: [
{
required: true
}
],
hide: true
},
costType: {
label: '费用类型',
rules: [
{
required: true,
message: '请输入费用类型',
trigger: 'blur'
}
]
},
constructContent: {
label: '建设内容',
span: 24,
type: 'textarea',
rules: [
{
required: true,
message: '请输入建设内容',
trigger: 'blur'
}
]
},
costName: {
label: '费用名称',
rules: [
{
required: true,
message: '请输入费用名称',
trigger: 'blur'
}
]
},
costDescribe: {
label: '费用描述',
span: 24,
type: 'textarea',
rules: [
{
required: true,
message: '请输入费用描述',
trigger: 'blur'
}
]
},
//
unit: {
label: '单位',
rules: [
{
required: true,
message: '请输入单位',
trigger: 'blur'
}
]
},
quantity: {
label: '数量',
type: 'number',
min: 1,
precision: 0,
rules: [
{
required: true,
message: '请输入数量',
trigger: 'blur'
}
]
},
unitPrice: {
label: '单价',
type: 'number',
min: 0,
precision: 2,
rules: [
{
required: true,
message: '请输入单价',
trigger: 'blur'
}
]
},
totalPrice: {
label: '总价',
disabled: true,
rules: [
{
required: true,
message: '请输入总价',
trigger: 'blur'
}
]
},
remarks: {
label: '备注'
}
}
}
}
},
methods: {
beforeInit() {
this.tableData = []
},
//
addrow() {
this.currentlevel = this.tableData.length + 1
this.$refs.crudRef.rowAdd()
},
addUpdate(row, index, done, loading) {
console.log('addUpdate', row)
done(row)
this.updatePrice()
},
rowSave(row, done) {
row.costTableId = this.entityData.id
row.parentId = this.parentId
row.id = new Date().getTime()
row.orderNo = this.currentlevel
this.currentlevel = undefined
this.parentId = undefined
console.log('rowSave', row, this.data)
done(row)
this.updatePrice()
},
rowDelete(row, index, done) {
console.log('rowDelete', row)
done(row)
this.updatePrice()
},
//
addChild(row, index) {
//
if (row.children && row.children.length > 0) {
this.curdForm.isDetail = row.children[0].isDetail
} else {
this.curdForm.isDetail = '0'
}
this.parentId = row.id
this.currentlevel =
row.orderNo + '-' + (row.children == undefined ? 1 : row.children.length + 1)
this.$refs.crudRef.rowAdd()
},
calculateSubtotal(item) {
if (item.isDetail == '1') {
return item.totalPrice
}
let subtotal = 0
if (item.children && item.children.length > 0) {
subtotal += item.children.reduce((acc, child) => acc + this.calculateSubtotal(child), 0)
}
item.totalPrice = subtotal
if (item.children) {
for (let i = 0; i < item.children.length; i++) {
if (item.children[i].isDetail == '0') {
//
item.children[i].totalPrice = this.calculateSubtotal(item.children[i])
}
}
}
return subtotal
},
updatePrice() {
this.entityData.totalInvestment = 0
if (this.tableData.length > 0) {
this.tableData.forEach((item) => {
this.calculateSubtotal(item)
this.entityData.totalInvestment += item.totalPrice
console.log('calculateSubtotal', item, this.entityData)
})
}
},
save() {
this.$refs.form.validate((valid) => {
if (valid) {
this.entityData.costItemDetailList = this.tableData
this.api.addCostTable(this.entityData).then((response) => {
this.$emit('refresh')
this.close()
})
}
})
},
updateCostInfo(val){
this.curdForm.costDescribe = val.modelDescription
this.curdForm.unitPrice=val.productPrice
}
},
computed: {
updatedTotal() {
return this.curdForm.unitPrice * this.curdForm.quantity
}
},
watch: {
//
'curdForm.isDetail'(val) {
console.log('isDetail', val, this.curdForm, this.defaults)
if (val == '0') {
//
this.defaults.costName.display = false
this.defaults.costDescribe.display = false
this.defaults.unit.display = false
this.defaults.quantity.display = false
this.defaults.unitPrice.display = false
this.defaults.totalPrice.display = false
this.curdForm.costName = ''
this.curdForm.costDescribe = ''
this.curdForm.unit = ''
this.curdForm.quantity = ''
this.curdForm.unitPrice = ''
this.curdForm.totalPrice = ''
this.defaults.costType.display = true
this.defaults.constructContent.display = true
} else {
this.defaults.costType.display = false
this.defaults.constructContent.display = false
this.curdForm.costType = ''
this.curdForm.constructContent = ''
this.defaults.costName.display = true
this.defaults.costDescribe.display = true
this.defaults.unit.display = true
this.defaults.quantity.display = true
this.defaults.unitPrice.display = true
this.defaults.totalPrice.display = true
}
},
updatedTotal(val) {
if (val == 0) {
this.curdForm.totalPrice = '' //0
return
}
this.curdForm.totalPrice = val //updatedTotal
},
tableData: {
handler(val, oldVal) {
console.log('tableData', val, oldVal)
},
deep: true
}
}
}
</script>
<style></style>

194
src/modules/costManagement/view/costTable/index.vue

@ -0,0 +1,194 @@
<template>
<avue-crud
ref="crudRef"
:option="option"
:data="data"
v-model="formData"
v-model:page="page"
v-model:search="queryCondition"
@row-del="rowDel"
@refresh-change="onLoad"
@on-load="onLoad"
@search-change="searchChange"
@row-dblclick="rowDblclick"
>
<template #menu-left="{}">
<el-button
type="primary"
icon="el-icon-plus"
@click="rowSave()"
v-permission="pageCode + 'add'"
>新增</el-button
>
</template>
<template #menu="{ row, index }">
<el-button
type="primary"
text
icon="el-icon-edit"
@click="rowUpdate(row)"
v-permission="pageCode + 'modify'"
>编辑</el-button
>
<el-popconfirm
title="此操作将删除数据, 是否继续?"
confirm-button-text="删除"
cancel-button-text="取消"
icon="el-icon-delete"
icon-color="red"
@confirm="rowDel(row, index)"
>
<template #reference>
<el-button type="primary" text icon="el-icon-delete" v-permission="pageCode + 'remove'"
>删除</el-button
>
</template>
</el-popconfirm>
</template>
</avue-crud>
<AddPage ref="addPage" @refresh="onLoad" />
<ModifyPage ref="modifyPage" @refresh="onLoad" />
<ViewPage ref="viewPage" />
</template>
<script setup>
import { ref, getCurrentInstance, reactive } from 'vue'
import AddPage from './add.vue'
import ModifyPage from './modify.vue'
import ViewPage from './view.vue'
//this
let { proxy } = getCurrentInstance()
const option = ref(null)
const data = ref(null)
let moduleParam = reactive({
entityType: 'personProductModel',
pageType: 'addOrModify'
})
let formData = ref({})
let queryCondition = ref({})
let pageInfo = reactive({
//
pageNum: 1,
//
pageSize: 10
})
//
let sortInfo = reactive({
sort_field: 'id',
sort_sortType: 'descending'
})
let page = reactive({
total: 0,
currentPage: 1,
pageSize: 10
})
const MODULE_CODE = 'costManagement'
const ENTITY_TYPE = 'costTable'
const pageCode = `${MODULE_CODE}:${ENTITY_TYPE}:`
const api = eval('proxy.$api.' + MODULE_CODE + '.' + ENTITY_TYPE)
option.value = {
dialogWidth: '80%', //
searchMenuSpan: 6, //
addBtn: false, //
editBtn: false, //
delBtn: false, //
column: [
{
label: '项目名称',
labelWidth: 120,
prop: 'projectName',
search: true,
searchLabelWidth: 120
},
{
label: '造价日期',
labelWidth: 120,
prop: 'costDate',
type: 'date',
format: 'YYYY-MM-DD',
search: true,
searchLabelWidth: 120
},
{
label: '总投资',
labelWidth: 120,
prop: 'totalInvestment',
type: 'number',
precision: 2,
mim: 0,
searchLabelWidth: 120,
disabled: true
}
]
// group: [
// {
// label: '',
// prop: 'jbxx',
// icon: 'el-icon-edit-outline',
// column: [
// {
// label: '',
// labelWidth: 120,
// prop: 'projectName',
// search: true,
// searchLabelWidth: 120,
// },
// {
// label: '',
// labelWidth: 120,
// prop: 'totalInvestment',
// type: 'number',
// precision: 2,
// mim: 0,
// searchLabelWidth: 120,
// disabled: true,
// }
// ]
// },
// {
// label: '',
// prop: 'jbxx',
// icon: 'el-icon-edit-outline',
// column: [
// {
// label: '',
// prop: 'id'
// },
// ]
// }
// ]
}
data.value = []
function rowSave(row, done, loading) {
proxy.$refs.addPage.init()
}
function rowDel(row, index) {
api.remove(row.id)
onLoad()
}
function rowUpdate(row, index, done, loading) {
proxy.$refs.modifyPage.init(row.id)
}
function onLoad() {
pageInfo.pageNum = page.currentPage
const params = Object.assign(queryCondition.value, pageInfo, sortInfo)
api.page(params).then((res) => {
data.value = res.data.records
page.total = res.data.total
// res.data.total
})
}
function rowDblclick(row, index) {
proxy.$refs.viewPage.init(row.id)
}
function searchChange(val, done) {
onLoad()
done()
}
</script>
<style>
.el-input,
.el-input-number {
width: 100% !important;
}
</style>

376
src/modules/costManagement/view/costTable/modify.vue

@ -0,0 +1,376 @@
<template>
<Dialog title="修改" v-model="visible" width="80%">
<el-form
ref="form"
:model="entityData"
:rules="rules"
label-width="120px"
label-position="right"
style="width: 90%; margin: 0px auto"
>
<!--表单区域 -->
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="entityData.projectName" />
</el-form-item>
<el-form-item label="总投资" prop="totalInvestment">
<el-input type="number" v-model="entityData.totalInvestment" disabled />
</el-form-item>
</el-form>
<!--表格区域-->
<avue-crud
ref="crudRef"
v-model="curdForm"
v-model:defaults="defaults"
:option="option"
:data="tableData"
@row-update="addUpdate"
@row-save="rowSave"
@row-del="rowDelete"
>
<template #orderNo="{ row }">
<el-tag type="success">{{ row.orderNo }}</el-tag>
</template>
<template #menu-left="{}">
<el-button
type="danger"
icon="el-icon-plus"
@click="addrow()"
v-permission="pageCode + 'add'"
>新增</el-button
>
</template>
<template #menu="{ row, index }">
<el-button text type="primary" @click="addChild(row, index)" v-if="row.isDetail == '0'"
>增加子项</el-button
>
</template>
<template #costName-form="{}">
<costTypeComponents v-model="curdForm.costName" :module-param="moduleParam" @updateCostInfo="updateCostInfo"/>
</template>
</avue-crud>
<template #footer>
<el-button type="primary" @click="save" v-permission="pageCode + 'add'">保存</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</template>
<script>
import { Dialog } from '@/components/abc/Dialog'
import costTypeComponents from '@/modules/costManagement/components/costTypeComponents.vue'
const MODULE_CODE = 'costManagement'
const ENTITY_TYPE = 'costTable'
export default {
name: ENTITY_TYPE + '-modify',
components: { Dialog,costTypeComponents },
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
entityData: {},
visible: false,
rules: {
//
projectName: [{ required: true, message: '【项目名称】不能为空', trigger: 'blur' }],
totalInvestment: [{ required: true, message: '【总投资】不能为空', trigger: 'blur' }]
},
tableData: [],
curdForm: {},
defaults: {},
parentId: undefined,
currentlevel: undefined,
currentRowData: {},
option: {
addBtn: false,
refreshBtn: false,
columnBtn: false,
gridBtn: false,
index: false,
rowKey: 'id',
rowParentKey: 'parentId',
menuWidth: 100,
column: {
orderNo: {
label: '序号',
display: false,
width:200
},
isDetail: {
label: '是否明细',
type: 'radio',
button: true,
dicData: [
{
label: '是',
value: '1'
},
{
label: '否',
value: '0'
}
],
value: '0',
rules: [
{
required: true
}
],
hide: true
},
costType: {
label: '费用类型',
rules: [
{
required: true,
message: '请输入费用类型',
trigger: 'blur'
}
]
},
constructContent: {
label: '建设内容',
span: 24,
type: 'textarea',
rules: [
{
required: true,
message: '请输入建设内容',
trigger: 'blur'
}
]
},
costName: {
label: '费用名称',
rules: [
{
required: true,
message: '请输入费用名称',
trigger: 'blur'
}
]
},
costDescribe: {
label: '费用描述',
span: 24,
type: 'textarea',
rules: [
{
required: true,
message: '请输入费用描述',
trigger: 'blur'
}
]
},
//
unit: {
label: '单位',
rules: [
{
required: true,
message: '请输入单位',
trigger: 'blur'
}
]
},
quantity: {
label: '数量',
type: 'number',
min: 1,
precision: 0,
rules: [
{
required: true,
message: '请输入数量',
trigger: 'blur'
}
]
},
unitPrice: {
label: '单价',
type: 'number',
min: 0,
precision: 2,
rules: [
{
required: true,
message: '请输入单价',
trigger: 'blur'
}
]
},
totalPrice: {
label: '总价',
disabled: true,
rules: [
{
required: true,
message: '请输入总价',
trigger: 'blur'
}
]
},
remarks: {
label: '备注'
}
}
}
}
},
methods: {
//
init(id) {
this.api.getCostTableDetail(id).then((res) => {
this.entityData = res.data
this.tableData = res.data.costItemDetailList
this.visible = true
})
},
//
addrow() {
this.currentlevel = this.tableData.length + 1
this.$refs.crudRef.rowAdd()
},
addUpdate(row, index, done, loading) {
console.log('addUpdate', row)
done(row)
this.updatePrice()
},
rowSave(row, done) {
row.costTableId = this.entityData.id
row.parentId = this.parentId
row.id = new Date().getTime()
row.orderNo = this.currentlevel
this.currentlevel = undefined
this.parentId = undefined
console.log('rowSave', row, this.data)
done(row)
this.updatePrice()
},
rowDelete(row, index, done) {
console.log('rowDelete', row)
done(row)
this.updatePrice()
},
//
addChild(row, index) {
//
if (row.children && row.children.length > 0) {
this.curdForm.isDetail = row.children[0].isDetail
} else {
this.curdForm.isDetail = '0'
}
this.parentId = row.id
this.currentlevel =
row.orderNo + '-' + (row.children == undefined ? 1 : row.children.length + 1)
this.$refs.crudRef.rowAdd()
},
calculateSubtotal(item) {
if (item.isDetail == '1') {
return item.totalPrice
}
let subtotal = 0
if (item.children && item.children.length > 0) {
subtotal += item.children.reduce((acc, child) => acc + this.calculateSubtotal(child), 0)
}
item.totalPrice = subtotal
if (item.children) {
for (let i = 0; i < item.children.length; i++) {
if (item.children[i].isDetail == '0') {
//
item.children[i].totalPrice = this.calculateSubtotal(item.children[i])
}
}
}
return subtotal
},
updatePrice() {
this.entityData.totalInvestment = 0
if (this.tableData.length > 0) {
this.tableData.forEach((item) => {
this.calculateSubtotal(item)
this.entityData.totalInvestment += item.totalPrice
console.log('calculateSubtotal', item, this.entityData)
})
}
},
save() {
this.$refs.form.validate((valid) => {
if (valid) {
this.entityData.costItemDetailList = this.tableData
this.api.modifyCostTable(this.entityData).then((response) => {
this.close()
})
}
})
},
updateCostInfo(val){
this.curdForm.costDescribe = val.modelDescription
this.curdForm.unitPrice=val.productPrice
},
close() {
this.visible = false
this.$emit('refresh')
}
},
computed: {
updatedTotal() {
return this.curdForm.unitPrice * this.curdForm.quantity
}
},
watch: {
//
'curdForm.isDetail'(val) {
console.log('isDetail', val, this.curdForm, this.defaults)
if (val == '0') {
//
this.defaults.costName.display = false
this.defaults.costDescribe.display = false
this.defaults.unit.display = false
this.defaults.quantity.display = false
this.defaults.unitPrice.display = false
this.defaults.totalPrice.display = false
this.curdForm.costName = ''
this.curdForm.costDescribe = ''
this.curdForm.unit = ''
this.curdForm.quantity = ''
this.curdForm.unitPrice = ''
this.curdForm.totalPrice = ''
this.defaults.costType.display = true
this.defaults.constructContent.display = true
} else {
this.defaults.costType.display = false
this.defaults.constructContent.display = false
this.curdForm.costType = ''
this.curdForm.constructContent = ''
this.defaults.costName.display = true
this.defaults.costDescribe.display = true
this.defaults.unit.display = true
this.defaults.quantity.display = true
this.defaults.unitPrice.display = true
this.defaults.totalPrice.display = true
}
},
updatedTotal(val) {
if (val == 0) {
this.curdForm.totalPrice = '' //0
return
}
this.curdForm.totalPrice = val //updatedTotal
},
tableData: {
handler(val, oldVal) {
console.log('tableData', val, oldVal)
},
deep: true
}
}
}
</script>
<style></style>

221
src/modules/costManagement/view/costTable/view.vue

@ -0,0 +1,221 @@
<template>
<Dialog title="查看" v-model="visible" width="80%">
<el-form
ref="form"
:model="entityData"
:rules="rules"
label-width="120px"
label-position="right"
style="width: 90%; margin: 0px auto"
>
<!--表单区域 -->
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="entityData.projectName" disabled />
</el-form-item>
<el-form-item label="总投资" prop="totalInvestment">
<el-input type="number" v-model="entityData.totalInvestment" disabled />
</el-form-item>
</el-form>
<!--表格区域-->
<avue-crud ref="crudRef" :option="option" :data="tableData" >
<template #orderNo="{ row }">
<el-tag type="success">{{ row.orderNo }}</el-tag>
</template>
</avue-crud>
<template #footer>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</template>
<script>
import { Dialog } from '@/components/abc/Dialog'
const MODULE_CODE = 'costManagement'
const ENTITY_TYPE = 'costTable'
export default {
name: ENTITY_TYPE + '-modify',
components: { Dialog },
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
entityData: {},
visible: false,
tableData: [],
option: {
addBtn: false,
refreshBtn: false,
columnBtn: false,
gridBtn: false,
index: false,
menu: false,
rowKey: 'id',
rowParentKey: 'parentId',
menuWidth: 100,
column: {
orderNo: {
label: '序号',
display: false,
width: 200
},
isDetail: {
label: '是否明细',
type: 'radio',
button: true,
dicData: [
{
label: '是',
value: '1'
},
{
label: '否',
value: '0'
}
],
value: '0',
rules: [
{
required: true
}
],
hide: true
},
costType: {
label: '费用类型',
rules: [
{
required: true,
message: '请输入费用类型',
trigger: 'blur'
}
]
},
constructContent: {
label: '建设内容',
span: 24,
type: 'textarea',
rules: [
{
required: true,
message: '请输入建设内容',
trigger: 'blur'
}
]
},
costName: {
label: '费用名称',
rules: [
{
required: true,
message: '请输入费用名称',
trigger: 'blur'
}
]
},
costDescribe: {
label: '费用描述',
span: 24,
type: 'textarea',
rules: [
{
required: true,
message: '请输入费用描述',
trigger: 'blur'
}
]
},
//
unit: {
label: '单位',
rules: [
{
required: true,
message: '请输入单位',
trigger: 'blur'
}
]
},
quantity: {
label: '数量',
type: 'number',
min: 1,
precision: 0,
rules: [
{
required: true,
message: '请输入数量',
trigger: 'blur'
}
]
},
unitPrice: {
label: '单价',
type: 'number',
min: 0,
precision: 2,
rules: [
{
required: true,
message: '请输入单价',
trigger: 'blur'
}
]
},
totalPrice: {
label: '总价',
disabled: true,
rules: [
{
required: true,
message: '请输入总价',
trigger: 'blur'
}
]
},
remarks: {
label: '备注'
}
}
}
}
},
methods: {
//
init(id) {
this.api.getCostTableDetail(id).then((res) => {
this.entityData = res.data
this.tableData = res.data.costItemDetailList
this.visible = true
})
},
close() {
this.visible = false
this.$emit('refresh')
},
spanMethod({ row, column, rowIndex, columnIndex }) {
console.log("row, column, rowIndex, columnIndex",row, column, rowIndex, columnIndex)
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
</script>
<style></style>

126
src/modules/productManagement/api/index.ts

@ -0,0 +1,126 @@
import { COMMON_METHOD } from '@/constant/common'
import request from '@/config/axios'
const moduleName = 'productManagement'
// 系统参数
// export const param = Object.assign({}, COMMON_METHOD, {
// serveUrl: '/' + moduleName + '/' + 'param' + '/'
// })
// 供应商管理
// export const supplierInformation = {
// serveUrl: '/' + moduleName + '/' + 'supplierInformation' + '/',
// page(params) {
// return request.get({ url: this.serveUrl + 'page', params })
// },
// get(id) {
// return request.get({ url: this.serveUrl + id })
// }
// }
// 供应商管理
export const supplierInformation = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'supplierInformation' + '/'
})
// 厂商产品管理
export const supplierProducts = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'supplierProducts' + '/'
})
// 公司产品
export const companyProducts = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'companyProducts' + '/'
})
// 个人产品
export const personProducts = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'personProducts' + '/'
})
// 供应商产品型号
export const supplierProductModel = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'supplierProductModel' + '/',
addModel(params) {
return request.post({ url: this.serveUrl + 'addModel', data: params })
},
modifyModel(params) {
return request.put({ url: this.serveUrl + 'modifyModel', data: params })
},
getModelDetails(modelId) {
return request.get({ url: this.serveUrl + 'getModelDetails/' + modelId })
}
})
// 公司产品型号
export const companyProductModel = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'companyProductModel' + '/',
addModel(params) {
return request.post({ url: this.serveUrl + 'addModel', data: params })
},
modifyModel(params) {
return request.put({ url: this.serveUrl + 'modifyModel', data: params })
},
getModelDetails(modelId) {
return request.get({ url: this.serveUrl + 'getModelDetails/' + modelId })
}
})
// 个人产品型号
export const personProductModel = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'personProductModel' + '/',
addModel(params) {
return request.post({ url: this.serveUrl + 'addModel', data: params })
},
modifyModel(params) {
return request.put({ url: this.serveUrl + 'modifyModel', data: params })
},
getModelDetails(modelId) {
return request.get({ url: this.serveUrl + 'getModelDetails/' + modelId })
}
})
// 产品型号管理
export const productModelTemplate = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'productModelTemplate' + '/'
})
// 产品型号规格管理
export const productModelTemplateDetails = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'productModelTemplateDetails' + '/',
addList(params) {
return request.post({ url: this.serveUrl + 'addList', data: params })
},
modifyList(params) {
return request.put({ url: this.serveUrl + 'modifyList', data: params })
}
})
// 用户设置
export const userProfile = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'userProfile' + '/'
})
// 系统管理
export const systemManage = Object.assign(
{},
{
serveUrl: '/' + moduleName + '/' + 'systemManage' + '/',
// 重建系统缓存
rebuildSystemCache() {
return request.put({ url: this.serveUrl + 'rebuildSystemCache' })
},
// 获取唯一性标识
getUniqueId() {
// 获取唯一性标识
return request.get({ url: this.serveUrl + 'getUniqueId' })
}
}
)
// 模块
export const module = Object.assign({}, COMMON_METHOD, {
serveUrl: '/' + moduleName + '/' + 'module' + '/'
})

251
src/modules/productManagement/components/productModelComponents.vue

@ -0,0 +1,251 @@
<template>
<div class="w-full">
<el-input type="textarea" v-model="displayName" disabled style="width: 100%" />
<el-button-group v-if="moduleParam.pageType != 'view'">
<el-button icon="grid" @click="init" style="border-left-width: 0; padding: 10px" />
<!-- <el-button icon="delete" @click="clear" style="border-left-width: 0; padding: 10px" /> -->
</el-button-group>
<Dialog title="模块选择" v-model="visible" class="w-150">
<el-form label-width="auto" :model="formData">
<el-form-item label="型号模板">
<product-model-select-components
v-model="formData.productModelTemplateId"
@updateTableData="updateTableData"
:module-param="moduleParam"
/>
<!-- <el-input v-model="formData.productModelTemplateId" style="width: 100%" /> -->
</el-form-item>
<el-form-item label="产品描述">
<el-input type="textarea" disabled v-model="formData.description" style="width: 100%" />
</el-form-item>
<el-form-item label="产品规格" style="margin-top: 20px">
<avue-crud
ref="crud"
:option="option"
:data="tableData"
@row-update="addUpdate"
@row-save="rowSave"
@row-del="rowDelete"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" @click="confirm">确定</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</div>
</template>
<script>
// import { referenceMixin } from '@/mixin/referenceMixin.js'
import { Dialog } from '@/components/abc/Dialog'
import { isEmpty } from '@/utils/is'
import productModelSelectComponents from '@/modules/productManagement/components/productModelSelectComponents.vue'
const MODULE_CODE = 'productManagement'
// const ENTITY_TYPE = 'supplierProductModel'
export default {
emits: ['update:modelValue', 'my-change'],
name: 'productModelComponents-reference',
components: { Dialog, productModelSelectComponents },
// mixins: [referenceMixin],
props: {
moduleParam: {
type: Object,
required: false
},
modelValue: {
type: String,
default: '',
required: false
}
},
data() {
return {
entityType: this.moduleParam.entityType,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
productModelApi: this.$api[MODULE_CODE][this.moduleParam.entityType], //eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
modelDetailsApi: eval('this.$api.' + MODULE_CODE + '.' + 'productModelTemplateDetails'),
pageCode: MODULE_CODE + ':' + this.moduleParam.entityType + ':',
sortInfo: {
sort_field: 'id',
sort_sortType: 'descending'
},
displayName: '',
visible: false,
loading: false,
tableData: [],
option: {
addBtn: false,
addRowBtn: true,
cellBtn: true,
refreshBtn: false,
columnBtn: false,
gridBtn: false,
// saveBtn: false,
menuWidth: 100,
column: [
{
label: '指标名称',
prop: 'paramName',
labelWidth: '120px',
sortable: true,
cell: true,
rules: [
{
required: true,
message: '请输入参数名称',
trigger: 'blur'
}
]
},
{
label: '指标参数',
labelWidth: '120px',
prop: 'parameterValue',
cell: true,
rules: [
{
required: true,
message: '请输入参数指标',
trigger: 'blur'
}
]
},
{
label: '是否关键指标',
labelWidth: '120px',
prop: 'isKeyParameter',
type: 'radio',
button: true,
dicData: [
{
label: '是',
value: '1'
},
{
label: '否',
value: '0'
}
],
value: '1',
required: true,
cell: true
}
]
},
queryCondition: {
//
app: ''
},
//
nameKey: 'supplierName',
formData: {
description: ''
// tableData:[]
}
}
},
watch: {
tableData: {
handler(newName, oldName) {
this.formData.description = ''
for (let i = 0; i < this.tableData.length; i++) {
let rowData = this.tableData[i]
if (!isEmpty(rowData.paramName)) {
this.formData.description =
// this.formData.description + rowData.paramName + ':' + rowData.parameterIndex + ';\n'
this.formData.description + rowData.paramName + ':' + rowData.parameterValue + ';'
}
}
},
immediate: true,
deep: true
},
modelValue: {
immediate: true,
handler: 'getSelectedName'
}
},
methods: {
//
init() {
if (!this.modelValue) {
this.productModelApi.init().then((res) => {
this.formData['id'] = res.data.id //id
console.log('厂商产品型号初始化', this.formData, res.data)
})
}
this.visible = true
},
//
clear() {
this.displayName = ''
this.$emit('update:modelValue', '')
this.$emit('my-change', '')
},
//
close() {
this.visible = false
},
//
async confirm() {
this.displayName = this.formData.description
//
//
this.formData.modelDeatils = this.tableData
this.loading = true
//modelValue
if (!this.modelValue) {
await this.productModelApi.addModel(this.formData)
} else {
await this.productModelApi.modifyModel(this.formData)
}
this.$emit('update:modelValue', this.formData['id'])
this.$emit('my-change', '')
this.loading = false
this.visible = false
},
getSelectedName() {
if (this.modelValue) {
this.productModelApi.get(this.modelValue).then((res) => {
this.displayName = res.data['description']
this.formData['id'] = this.modelValue
this.formData['productModelTemplateId'] = res.data['productModelTemplateId']
})
//
this.productModelApi.getModelDetails(this.modelValue).then((res) => {
this.tableData = res.data
})
}
},
addUpdate(form, index, done, loading) {
done()
},
rowSave(form, done) {
done()
},
rowDelete(form, index, done) {
done()
},
updateTableData() {
console.log('updateTableData', this.tableData)
this.tableData = []
this.modelDetailsApi
.list({ modelTemplateId: this.formData.productModelTemplateId })
.then((res) => {
res.data.forEach((item) => {
this.tableData.push({
paramName: item.paramName,
isKeyParameter: item.isKeyParameter,
$cellEdit: true
})
})
})
}
}
}
</script>
<style></style>

141
src/modules/productManagement/components/productModelSelectComponents.vue

@ -0,0 +1,141 @@
<template>
<div class="w-full">
<el-input v-model="displayName" disabled style="width: 152px" />
<el-button-group>
<el-button icon="grid" @click="init" style="border-left-width: 0; padding: 10px" />
<!-- <el-button icon="delete" @click="clear" style="border-left-width: 0; padding: 10px" /> -->
</el-button-group>
<Dialog title="模块选择" v-model="visible" class="w-150">
<CollapseTab>
<el-form :inline="true" :model="queryCondition" label-width="80px" @keyup.enter="query">
<!--查询条件区 -->
<el-form-item label="型号名称">
<dictionary-select v-model="queryCondition.templateName" code="AppCode" />
</el-form-item>
<el-form-item label="型号规格">
<QueryText v-model="queryCondition.templateDetailsDescription" type="LK" />
</el-form-item>
<el-form-item label="类型">
<QueryText v-model="queryCondition.templateType" type="LK" />
</el-form-item>
<el-form-item style="float: right">
<QueryButton :page-code="pageCode" />
</el-form-item>
<div class="clearfix"></div>
</el-form>
</CollapseTab>
<el-card style="width: 100%">
<div style="float: right; margin-top: 0; margin-bottom: 10px">
<ColumnsController :value="columnList" :tableKey="tableKey" />
</div>
<el-table
v-loading="loading"
:data="tableData"
style="width: 100%"
highlight-current-row
border
@sort-change="sortChange"
@current-change="rowChange"
>
<el-table-column
v-for="(item, index) in showCols"
:key="index"
:label="item.label"
:prop="item.prop"
:show-overflow-tooltip="item.showOverflowTooltip"
:width="item.width"
:formatter="item.formatFunc"
:sortable="item.sortable"
/>
</el-table>
<ListPager
:page-num="pageInfo.pageNum"
:page-size="pageInfo.pageSize"
:page-total="pageTotal"
/>
</el-card>
<template #footer>
<el-button type="primary" @click="confirm">确定</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</div>
</template>
<script>
import { referenceMixin_copy } from '@/mixin/referenceMixin_copy.js'
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'productModelTemplate'
export default {
name: ENTITY_TYPE + '-reference',
components: {},
mixins: [referenceMixin_copy],
props: {
moduleParam: {
type: Object,
required: false
},
modelSelectData: {
type: Object,
required: false
}
},
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
sortInfo: {
sort_field: 'id',
sort_sortType: 'descending'
},
columnList: [
{
prop: 'templateName',
label: '型号名称',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
label: '型号规格',
prop: 'templateDetailsDescription',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
label: '类型',
prop: 'templateType',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
label: '备注',
prop: 'remarks',
show: true,
showOverflowTooltip: true,
sortable: true
}
],
queryCondition: {
//
app: ''
},
//
nameKey: 'templateName'
}
},
methods: {
afterConfirm(param){
this.$emit('updateTableData')
}
}
}
</script>
<style></style>

220
src/modules/productManagement/components/productModelTemplateComponents.vue

@ -0,0 +1,220 @@
<template>
<div class="w-full">
<el-input type="textarea" v-model="displayName" disabled style="width: 100%" />
<el-button-group v-if="moduleParam.pageType != 'view'">
<el-button icon="grid" @click="init" style="border-left-width: 0; padding: 10px" />
</el-button-group>
<Dialog title="模块选择" v-model="visible" class="w-150">
<el-form label-width="auto" :model="formData">
<el-form-item label="产品规格" style="margin-top: 20px">
<avue-crud
ref="crud"
:option="option"
:data="tableData"
@row-update="addUpdate"
@row-save="rowSave"
@row-del="rowDelete"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" @click="confirm">确定</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</div>
</template>
<script>
// import { referenceMixin } from '@/mixin/referenceMixin.js'
import { Dialog } from '@/components/abc/Dialog'
import { isEmpty } from '@/utils/is'
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'productModelTemplateDetails'
export default {
name: ENTITY_TYPE + '-reference',
components: { Dialog },
emits: ['update:modelValue', 'my-change'],
// mixins: [referenceMixin],
props: {
// tableData: {
// handler(newName, oldName) {
// // this. = ''
// for (let i = 0; i < this.tableData.length; i++) {
// let rowData = this.tableData[i]
// if (!isEmpty(rowData.paramName)) {
// this.formData.description =
// // this.formData.description + rowData.paramName + ':' + rowData.parameterIndex + ';\n'
// this.formData.description + rowData.paramName +';'
// }
// }
// },
// immediate: true,
// deep: true
// },
moduleParam: {
type: Object,
required: false
},
modelValue: {
type: String,
default: '',
required: false
}
},
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
ModelTemplateDetailsApi: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
sortInfo: {
sort_field: 'id',
sort_sortType: 'descending'
},
displayName: '',
visible: false,
loading: false,
tableData: [],
option: {
addBtn: false,
addRowBtn: true,
cellBtn: true,
refreshBtn: false,
columnBtn: false,
gridBtn: false,
// saveBtn: false,
menuWidth: 100,
column: [
{
label: '指标名称',
prop: 'paramName',
labelWidth: '120px',
sortable: true,
cell: true,
rules: [
{
required: true,
message: '请输入参数名称',
trigger: 'blur'
}
]
},
{
label: '是否关键指标',
labelWidth: '120px',
prop: 'isKeyParameter',
type: 'radio',
button: true,
dicData: [
{
label: '是',
value: '1'
},
{
label: '否',
value: '0'
}
],
value: '1',
required: true,
cell: true
}
]
},
queryCondition: {
//
app: ''
},
//
nameKey: 'supplierName',
formData: {},
modelTemplateId: ''
}
},
watch: {
modelValue: {
immediate: true,
handler: 'getSelectedName'
}
},
methods: {
//
init() {
if (!this.modelValue) {
this.ModelTemplateDetailsApi.init().then((res) => {
this.modelTemplateId = res.data.id //id
console.log('厂商产品型号初始化', this.formData, res.data)
})
}
this.visible = true
},
//
clear() {
this.displayName = ''
this.$emit('update:modelValue', '')
this.$emit('my-change', '')
},
//
close() {
this.visible = false
},
//
async confirm() {
//
//
this.loading = true
//modelTemplateId
this.displayName = ''
for (let i = 0; i < this.tableData.length; i++) {
let rowData = this.tableData[i]
if (!isEmpty(rowData.paramName)) {
this.tableData[i].modelTemplateId = this.modelTemplateId
this.displayName = this.displayName + rowData.paramName + ';'
}
}
//modelValue
if (!this.modelValue) {
await this.ModelTemplateDetailsApi.addList(this.tableData)
} else {
await this.ModelTemplateDetailsApi.modifyList(this.tableData)
}
this.$emit('update:modelValue', this.modelTemplateId)
this.$emit('my-change', '')
this.loading = false
this.visible = false
},
getSelectedName() {
if (this.modelValue) {
this.modelTemplateId = this.modelValue
this.ModelTemplateDetailsApi.list({ modelTemplateId: this.modelValue }).then((res) => {
//
if (isEmpty(this.displayName)) {
res.data.forEach((item) => {
this.displayName = this.displayName + item.paramName + ';'
})
}
//tabletData
if (isEmpty(this.tableData)) {
this.tableData = res.data
}
})
}
},
addUpdate(form, index, done, loading) {
done()
},
rowSave(form, done) {
done()
},
rowDelete(form, index, done) {
done()
}
}
}
</script>
<style></style>

145
src/modules/productManagement/components/supplierInformationComponents.vue

@ -0,0 +1,145 @@
<template>
<div class="w-full">
<el-input v-model="displayName" disabled style="width: 152px" />
<el-button-group>
<el-button icon="grid" @click="init" style="border-left-width: 0; padding: 10px" />
<el-button icon="delete" @click="clear" style="border-left-width: 0; padding: 10px" />
</el-button-group>
<Dialog title="模块选择" v-model="visible" class="w-150">
<CollapseTab>
<el-form :inline="true" :model="queryCondition" label-width="80px" @keyup.enter="query">
<el-form-item label="供应商名称">
<QueryText v-model="queryCondition.supplierName" type="LK" />
</el-form-item>
<el-form-item label="供应商联系人">
<QueryText v-model="queryCondition.supplierContacts" type="LK" />
</el-form-item>
<el-form-item label="供应商联系电话">
<QueryText v-model="queryCondition.supplierContactsPhone" type="LK" />
</el-form-item>
<el-form-item label="供应商类型">
<QueryText v-model="queryCondition.supplierType" type="LK" />
</el-form-item>
<el-form-item style="float: right">
<QueryButton :page-code="pageCode" />
</el-form-item>
<div class="clearfix"></div>
</el-form>
</CollapseTab>
<el-card style="width: 100%">
<div style="float: right; margin-top: 0; margin-bottom: 10px">
<el-button v-permission="pageCode + 'add'" type="primary" icon="plus" @click="add"
>新增供应商</el-button
>
<ColumnsController :value="columnList" :tableKey="tableKey" />
</div>
<el-table
v-loading="loading"
:data="tableData"
style="width: 100%"
highlight-current-row
border
@sort-change="sortChange"
@current-change="rowChange"
>
<el-table-column
v-for="(item, index) in showCols"
:key="index"
:label="item.label"
:prop="item.prop"
:show-overflow-tooltip="item.showOverflowTooltip"
:width="item.width"
:formatter="item.formatFunc"
:sortable="item.sortable"
/>
</el-table>
<ListPager
:page-num="pageInfo.pageNum"
:page-size="pageInfo.pageSize"
:page-total="pageTotal"
/>
</el-card>
<template #footer>
<el-button type="primary" @click="confirm">确定</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
<AddPage ref="addPage" @refresh="refresh" />
</div>
</template>
<script>
import { referenceMixin } from '@/mixin/referenceMixin.js'
import AddPage from '@/modules/productManagement/view/supplierInformation/add.vue'
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'supplierInformation'
export default {
name: ENTITY_TYPE + '-reference',
components: { AddPage },
mixins: [referenceMixin],
props: {
moduleParam: {
type: Object,
required: false
}
},
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
sortInfo: {
sort_field: 'id',
sort_sortType: 'descending'
},
columnList: [
{
prop: 'supplierName',
label: '供应商名称',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
prop: 'supplierContacts',
label: '供应商联系人',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
prop: 'supplierContactsPhone',
label: '供应商联系电话',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
prop: 'supplierType',
label: '供应商类型',
show: true,
showOverflowTooltip: true,
sortable: true
}
],
queryCondition: {
//
app: ''
},
//
nameKey: 'supplierName'
}
},
methods: {
//
add() {
this.$refs.addPage.init()
}
}
}
</script>
<style></style>

209
src/modules/productManagement/view/companyProducts/index.vue

@ -0,0 +1,209 @@
<template>
<avue-crud
ref="crudRef"
:option="option"
:data="data"
v-model="formData"
v-model:page="page"
v-model:search="queryCondition"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
@refresh-change="onLoad"
@on-load="onLoad"
@search-change="searchChange"
@row-dblclick="rowDblclick"
>
<template #menu-left="{}">
<el-button
type="primary"
icon="el-icon-plus"
@click="proxy.$refs.crudRef.rowAdd()"
v-permission="pageCode + 'add'"
>新增</el-button
>
</template>
<template #menu="{ row, index }">
<el-button
type="primary"
text
icon="el-icon-edit"
@click="proxy.$refs.crudRef.rowEdit(row)"
v-permission="pageCode + 'modify'"
>编辑</el-button
>
<el-popconfirm
title="此操作将删除数据, 是否继续?"
confirm-button-text="删除"
cancel-button-text="取消"
icon="el-icon-delete"
icon-color="red"
@confirm="rowDel(row, index)"
>
<template #reference>
<el-button type="primary" text icon="el-icon-delete" v-permission="pageCode + 'remove'"
>删除</el-button
>
</template>
</el-popconfirm>
</template>
<template #supplierName-form="{}">
<supplier-information-components
v-model="formData.supplierInformationId"
:module-param="moduleParam"
/>
</template>
<template #modelId-form="{}">
<product-model-components v-model="formData.modelId" :module-param="moduleParam" />
</template>
</avue-crud>
</template>
<script setup>
import { ref, getCurrentInstance, reactive } from 'vue'
import supplierInformationComponents from '@/modules/productManagement/components/supplierInformationComponents.vue'
import productModelComponents from '@/modules/productManagement/components/productModelComponents.vue'
//this
let { proxy } = getCurrentInstance()
const option = ref(null)
const data = ref(null)
let moduleParam = reactive({
entityType: 'companyProductModel',
pageType: 'addOrModify'
})
let formData = ref({})
let queryCondition = ref({})
let pageInfo = reactive({
//
pageNum: 1,
//
pageSize: 10
})
//
let sortInfo = reactive({
sort_field: 'id',
sort_sortType: 'descending'
})
let page = reactive({
total: 0,
currentPage: 1,
pageSize: 10
})
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'companyProducts'
const pageCode = `${MODULE_CODE}:${ENTITY_TYPE}:`
const api = eval('proxy.$api.' + MODULE_CODE + '.' + ENTITY_TYPE)
option.value = {
dialogWidth: '80%', //
searchMenuSpan: 6, //
addBtn: false, //
editBtn: false, //
delBtn: false, //
column: [
{
label: '产品名称',
labelWidth: 120,
prop: 'productName', //sProductName
search: true,
searchLabelWidth: 120
},
{
label: '产品标识(型号)',
labelWidth: 120,
prop: 'productIdentity',
search: true,
searchLabelWidth: 120
},
{
label: '供应商名称',
labelWidth: 120,
prop: 'supplierName',
type: 'input',
hide: true,
searchLabelWidth: 120,
span: 12
},
{
label: '产品价格',
prop: 'productPrice',
labelWidth: 120,
type: 'number',
precision: 2,
mim: 0
},
{
label: '产品型号',
labelWidth: 120,
prop: 'modelId',
type: 'textarea',
hide: true,
minRows: 4 //
},
{
label: '产品描述',
labelWidth: 120,
prop: 'modelDescription',
//editDisabled: true //
display: false //
},
{
label: '信息来源',
labelWidth: 120,
prop: 'sourceInformation',
hide: true
},
{
label: '备注',
labelWidth: 120,
prop: 'remarks',
hide: true
}
]
}
data.value = []
function rowSave(row, done, loading) {
api.add(row).then(() => {
done()
onLoad()
}).catch(() => {
loading()
})
}
function rowDel(row, index) {
api.remove(row.id)
onLoad()
}
function rowUpdate(row, index, done, loading) {
api.modify(row).then(() => {
done()
onLoad()
}).catch(() => {
loading()
})
// done()
}
function onLoad() {
pageInfo.pageNum = page.currentPage
const params = Object.assign(queryCondition.value, pageInfo, sortInfo)
api.page(params).then((res) => {
data.value = res.data.records
page.total = res.data.total
// res.data.total
})
}
function rowDblclick(row, index) {
proxy.$refs.crudRef.rowView(row)
}
function searchChange(val, done) {
onLoad()
done()
}
</script>
<style>
.el-input,
.el-input-number {
width: 100% !important;
}
</style>

208
src/modules/productManagement/view/personProducts/index.vue

@ -0,0 +1,208 @@
<template>
<avue-crud
ref="crudRef"
:option="option"
:data="data"
v-model="formData"
v-model:page="page"
v-model:search="queryCondition"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
@refresh-change="onLoad"
@on-load="onLoad"
@search-change="searchChange"
@row-dblclick="rowDblclick"
>
<template #menu-left="{}">
<el-button
type="primary"
icon="el-icon-plus"
@click="proxy.$refs.crudRef.rowAdd()"
v-permission="pageCode + 'add'"
>新增</el-button
>
</template>
<template #menu="{ row, index }">
<el-button
type="primary"
text
icon="el-icon-edit"
@click="proxy.$refs.crudRef.rowEdit(row)"
v-permission="pageCode + 'modify'"
>编辑</el-button
>
<el-popconfirm
title="此操作将删除数据, 是否继续?"
confirm-button-text="删除"
cancel-button-text="取消"
icon="el-icon-delete"
icon-color="red"
@confirm="rowDel(row, index)"
>
<template #reference>
<el-button type="primary" text icon="el-icon-delete" v-permission="pageCode + 'remove'"
>删除</el-button
>
</template>
</el-popconfirm>
</template>
<template #supplierName-form="{}">
<supplier-information-components
v-model="formData.supplierInformationId"
:module-param="moduleParam"
/>
</template>
<template #modelId-form="{}">
<product-model-components v-model="formData.modelId" :module-param="moduleParam" />
</template>
</avue-crud>
</template>
<script setup>
import { ref, getCurrentInstance, reactive } from 'vue'
import supplierInformationComponents from '@/modules/productManagement/components/supplierInformationComponents.vue'
import productModelComponents from '@/modules/productManagement/components/productModelComponents.vue'
//this
let { proxy } = getCurrentInstance()
const option = ref(null)
const data = ref(null)
let moduleParam = reactive({
entityType: 'personProductModel',
pageType: 'addOrModify'
})
let formData = ref({})
let queryCondition = ref({})
let pageInfo = reactive({
//
pageNum: 1,
//
pageSize: 10
})
//
let sortInfo = reactive({
sort_field: 'id',
sort_sortType: 'descending'
})
let page = reactive({
total: 0,
currentPage: 1,
pageSize: 10
})
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'personProducts'
const pageCode = `${MODULE_CODE}:${ENTITY_TYPE}:`
const api = eval('proxy.$api.' + MODULE_CODE + '.' + ENTITY_TYPE)
option.value = {
dialogWidth: '80%', //
searchMenuSpan: 6, //
addBtn: false, //
editBtn: false, //
delBtn: false, //
column: [
{
label: '产品名称',
labelWidth: 120,
prop: 'productName', //sProductName
search: true,
searchLabelWidth: 120
},
{
label: '产品标识(型号)',
labelWidth: 120,
prop: 'productIdentity',
search: true,
searchLabelWidth: 120
},
{
label: '供应商名称',
labelWidth: 120,
prop: 'supplierName',
type: 'input',
hide: true,
searchLabelWidth: 120,
span: 12
},
{
label: '产品价格',
prop: 'productPrice',
labelWidth: 120,
type: 'number',
precision: 2,
mim: 0
},
{
label: '产品型号',
labelWidth: 120,
prop: 'modelId',
type: 'textarea',
hide: true,
minRows: 4 //
},
{
label: '产品描述',
labelWidth: 120,
prop: 'modelDescription',
//editDisabled: true //
display: false //
},
{
label: '信息来源',
labelWidth: 120,
prop: 'sourceInformation',
hide: true
},
{
label: '备注',
labelWidth: 120,
prop: 'remarks',
hide: true
}
]
}
data.value = []
function rowSave(row, done, loading) {
api.add(row).then(() => {
done()
onLoad()
}).catch(() => {
loading()
})
}
function rowDel(row, index) {
api.remove(row.id)
onLoad()
}
function rowUpdate(row, index, done, loading) {
api.modify(row).then(() => {
done()
onLoad()
}).catch(() => {
loading()
})
}
function onLoad() {
pageInfo.pageNum = page.currentPage
const params = Object.assign(queryCondition.value, pageInfo, sortInfo)
api.page(params).then((res) => {
data.value = res.data.records
page.total = res.data.total
// res.data.total
})
}
function rowDblclick(row, index) {
proxy.$refs.crudRef.rowView(row)
}
function searchChange(val, done) {
onLoad()
done()
}
</script>
<style>
.el-input,
.el-input-number {
width: 100% !important;
}
</style>

167
src/modules/productManagement/view/productModelTemplate/index.vue

@ -0,0 +1,167 @@
<template>
<avue-crud
ref="crudRef"
:option="option"
:data="data"
v-model="formData"
v-model:page="page"
v-model:search="queryCondition"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
@refresh-change="onLoad"
@on-load="onLoad"
@search-change="searchChange"
@row-dblclick="rowDblclick"
:before-close="beforeCloseForm"
>
<template #menu-left="{}">
<el-button
type="primary"
icon="el-icon-plus"
@click="proxy.$refs.crudRef.rowAdd()"
v-permission="pageCode + 'add'"
>新增</el-button
>
</template>
<template #menu="{ row, index }">
<el-button
type="primary"
text
icon="el-icon-edit"
@click="proxy.$refs.crudRef.rowEdit(row)"
v-permission="pageCode + 'modify'"
>编辑</el-button
>
<el-popconfirm
title="此操作将删除数据, 是否继续?"
confirm-button-text="删除"
cancel-button-text="取消"
icon="el-icon-delete"
icon-color="red"
@confirm="rowDel(row, index)"
>
<template #reference>
<el-button type="primary" text icon="el-icon-delete" v-permission="pageCode + 'remove'"
>删除</el-button
>
</template>
</el-popconfirm>
</template>
<template #templateDetailsDescription-form="{}">
<productModelTemplateComponents v-model="formData.id" :module-param="moduleParam" />
</template>
</avue-crud>
</template>
<script setup>
import { ref, getCurrentInstance, reactive } from 'vue'
import productModelTemplateComponents from '@/modules/productManagement/components/productModelTemplateComponents.vue'
//this
let { proxy } = getCurrentInstance()
const option = ref(null)
const data = ref(null)
let queryCondition = ref({})
let formData = ref({})
let moduleParam = reactive({
pageType: 'addOrModify'
})
let pageInfo = reactive({
//
pageNum: 1,
//
pageSize: 10
})
//
let sortInfo = reactive({
sort_field: 'id',
sort_sortType: 'descending'
})
let page = reactive({
total: 0,
currentPage: 1,
pageSize: 10
})
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'productModelTemplate'
const pageCode = `${MODULE_CODE}:${ENTITY_TYPE}:`
const api = eval('proxy.$api.' + MODULE_CODE + '.' + ENTITY_TYPE)
option.value = {
dialogWidth: '80%', //
searchMenuSpan: 6, //
addBtn: false, //
editBtn: false, //
delBtn: false, //
column: [
{
label: '型号名称',
labelWidth: 120,
prop: 'templateName', //sProductName
search: true,
searchLabelWidth: 120
},
{
label: '型号规格',
prop: 'templateDetailsDescription',
labelWidth: 120
},
{
label: '类型',
labelWidth: 120,
prop: 'templateType'
},
{
label: '备注',
labelWidth: 120,
prop: 'remarks'
}
]
}
data.value = []
function rowSave(row, done, loading) {
api.add(row).then((res) => {
onLoad()
done()
})
}
function rowDel(row, index) {
api.remove(row.id).then(() => {
onLoad()
})
}
function rowUpdate(row, index, done, loading) {
api.modify(row).then(() => {
onLoad()
done()
})
}
function onLoad() {
pageInfo.pageNum = page.currentPage
const params = Object.assign(queryCondition.value, pageInfo, sortInfo)
api.page(params).then((res) => {
data.value = res.data.records
page.total = res.data.total
// res.data.total
})
}
function rowDblclick(row, index) {
moduleParam.pageType = 'view'
proxy.$refs.crudRef.rowView(row)
}
//
function beforeCloseForm(done, type) {
done()
moduleParam.pageType = 'addOrModify' //
}
function searchChange(val, done) {
onLoad()
done()
}
</script>
<style>
.el-input,
.el-input-number {
width: 100% !important;
}
</style>

69
src/modules/productManagement/view/supplierInformation/add.vue

@ -0,0 +1,69 @@
<template>
<Dialog title="新增" v-model="visible" width="500px">
<el-form
ref="form"
:model="entityData"
:rules="rules"
label-width="120px"
label-position="right"
style="width: 90%; margin: 0px auto"
>
<!--表单区域 -->
<el-form-item label="供应商名称" prop="supplierName">
<el-input v-model="entityData.supplierName" />
</el-form-item>
<el-form-item label="供应商联系人" prop="supplierContacts">
<el-input v-model="entityData.supplierContacts" />
</el-form-item>
<el-form-item label="供应商联系电话" prop="supplierContactsPhone">
<el-input v-model="entityData.supplierContactsPhone" />
</el-form-item>
<el-form-item label="供应商类型" prop="supplierType">
<el-input v-model="entityData.supplierType" />
</el-form-item>
<el-form-item label="职位" prop="position">
<el-input v-model="entityData.position" />
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" @click="save" v-permission="pageCode + 'add'">保存</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</template>
<script>
import { addMixin } from '@/mixin/addMixin.js'
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'supplierInformation'
export default {
name: ENTITY_TYPE + '-add',
mixins: [addMixin],
components: {},
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
entityData: {},
rules: {
//
supplierName: [{ required: true, message: '【供应商名称】不能为空', trigger: 'blur' }],
supplierContacts: [
{ required: true, message: '【供应商联系人】不能为空', trigger: 'blur' }
],
supplierContactsPhone: [
{ required: true, message: '【供应商联系电话】不能为空', trigger: 'blur' }
],
supplierType: [{ required: true, message: '【供应商类型】不能为空', trigger: 'blur' }],
position: [{ required: true, message: '【职位】不能为空', trigger: 'blur' }]
}
}
},
methods: {}
}
</script>
<style></style>

148
src/modules/productManagement/view/supplierInformation/index.vue

@ -0,0 +1,148 @@
<template>
<ContentWrap>
<CollapseTab>
<el-form :inline="true" :model="queryCondition" label-width="120px" @keyup.enter="query">
<!--查询条件区 -->
<el-form-item label="供应商名称">
<QueryText v-model="queryCondition.supplierName" type="LK" />
</el-form-item>
<el-form-item label="供应商联系人">
<QueryText v-model="queryCondition.supplierContacts" type="LK" />
</el-form-item>
<el-form-item label="供应商联系电话">
<QueryText v-model="queryCondition.supplierContactsPhone" type="LK" />
</el-form-item>
<el-form-item label="供应商类型">
<QueryText v-model="queryCondition.supplierType" type="LK" />
</el-form-item>
<el-form-item style="float: right">
<QueryButton :page-code="pageCode" />
</el-form-item>
<div class="clearfix"></div>
</el-form>
</CollapseTab>
<div class="mb-10px mt-10px">
<el-button type="primary" icon="Refresh" @click="refresh">刷新</el-button>
<el-button v-permission="pageCode + 'add'" type="primary" icon="plus" @click="add"
>新增</el-button
>
</div>
<el-card style="width: 100%">
<div style="margin-top: 0; margin-bottom: 10px; float: right">
<ColumnsController :value="columnList" :tableKey="tableKey" />
</div>
<el-table
v-loading="loading"
:data="tableData"
style="width: 100%"
highlight-current-row
border
@sort-change="sortChange"
@current-change="rowChange"
@selection-change="selectionChange"
@row-dblclick="rowDoubleClick"
>
<el-table-column type="selection" width="55" />
<el-table-column
v-for="(item, index) in showCols"
:key="index"
:label="item.label"
:prop="item.prop"
:show-overflow-tooltip="item.showOverflowTooltip"
:width="item.width"
:formatter="item.formatFunc"
:sortable="item.sortable"
/>
<el-table-column fixed="right" label="操作" width="250">
<template #default="scope">
<el-button v-permission="pageCode + 'modify'" type="primary" @click="modify(scope.row)"
>修改</el-button
>
<el-button v-permission="pageCode + 'remove'" type="primary" @click="remove(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<ListPager
:page-num="pageInfo.pageNum"
:page-size="pageInfo.pageSize"
:page-total="pageTotal"
/>
</el-card>
<AddPage ref="addPage" @refresh="refresh" />
<ModifyPage ref="modifyPage" @refresh="refresh" />
<ViewPage ref="viewPage" />
</ContentWrap>
</template>
<script lang="ts">
import { listMixin } from '@/mixin/listMixin.js'
import AddPage from './add.vue'
import ModifyPage from './modify.vue'
import ViewPage from './view.vue'
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'supplierInformation'
export default {
name: ENTITY_TYPE,
mixins: [listMixin],
components: {
AddPage,
ModifyPage,
ViewPage
},
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
//
sortInfo: {
sort_field: 'id',
sort_sortType: 'descending'
},
columnList: [
{
prop: 'supplierName',
label: '供应商名称',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
prop: 'supplierContacts',
label: '供应商联系人',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
prop: 'supplierContactsPhone',
label: '供应商联系电话',
show: true,
showOverflowTooltip: true,
sortable: true
},
{
prop: 'supplierType',
label: '供应商类型',
show: true,
showOverflowTooltip: true,
sortable: true
}
],
queryCondition: {
//
}
}
},
methods: {}
}
</script>

69
src/modules/productManagement/view/supplierInformation/modify.vue

@ -0,0 +1,69 @@
<template>
<Dialog title="修改" v-model="visible" width="500px">
<el-form
ref="form"
:model="entityData"
:rules="rules"
label-width="120px"
label-position="right"
style="width: 90%; margin: 0px auto"
>
<!--表单区域 -->
<el-form-item label="供应商名称" prop="supplierName">
<el-input v-model="entityData.supplierName" />
</el-form-item>
<el-form-item label="供应商联系人" prop="supplierContacts">
<el-input v-model="entityData.supplierContacts" />
</el-form-item>
<el-form-item label="供应商联系电话" prop="supplierContactsPhone">
<el-input v-model="entityData.supplierContactsPhone" />
</el-form-item>
<el-form-item label="供应商类型" prop="supplierType">
<el-input v-model="entityData.supplierType" />
</el-form-item>
<el-form-item label="职位" prop="position">
<el-input v-model="entityData.position" />
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" @click="save" v-permission="pageCode + 'modify'">保存</el-button>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</template>
<script>
import { modifyMixin } from '@/mixin/modifyMixin.js'
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'supplierInformation'
export default {
name: ENTITY_TYPE + '-modify',
mixins: [modifyMixin],
components: {},
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
entityData: {},
rules: {
//
supplierName: [{ required: true, message: '【供应商名称】不能为空', trigger: 'blur' }],
supplierContacts: [
{ required: true, message: '【供应商联系人】不能为空', trigger: 'blur' }
],
supplierContactsPhone: [
{ required: true, message: '【供应商联系电话】不能为空', trigger: 'blur' }
],
supplierType: [{ required: true, message: '【供应商类型】不能为空', trigger: 'blur' }],
position: [{ required: true, message: '【职位】不能为空', trigger: 'blur' }]
}
}
},
methods: {}
}
</script>
<style></style>

55
src/modules/productManagement/view/supplierInformation/view.vue

@ -0,0 +1,55 @@
<template>
<Dialog title="查看" v-model="visible" width="500px">
<el-form
ref="form"
:model="entityData"
label-width="120px"
label-position="right"
style="width: 90%; margin: 0px auto"
>
<!--表单区域 -->
<el-form-item label="供应商名称" prop="supplierName">
<el-input v-model="entityData.supplierName" />
</el-form-item>
<el-form-item label="供应商联系人" prop="supplierContacts">
<el-input v-model="entityData.supplierContacts" />
</el-form-item>
<el-form-item label="供应商联系电话" prop="supplierContactsPhone">
<el-input v-model="entityData.supplierContactsPhone" />
</el-form-item>
<el-form-item label="供应商类型" prop="supplierType">
<el-input v-model="entityData.supplierType" />
</el-form-item>
<el-form-item label="职位" prop="position">
<el-input v-model="entityData.position" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="close">关闭</el-button>
</template>
</Dialog>
</template>
<script>
import { viewMixin } from '@/mixin/viewMixin.js'
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'supplierInformation'
export default {
name: ENTITY_TYPE + '-view',
mixins: [viewMixin],
components: {},
data() {
return {
entityType: ENTITY_TYPE,
moduleCode: MODULE_CODE,
// eslint-disable-next-line no-eval
api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
entityData: {}
}
},
methods: {}
}
</script>
<style></style>

220
src/modules/productManagement/view/supplierProducts/index.vue

@ -0,0 +1,220 @@
<template>
<avue-crud
ref="crudRef"
:option="option"
:data="data"
v-model="formData"
v-model:page="page"
v-model:search="queryCondition"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
@refresh-change="onLoad"
@on-load="onLoad"
@search-change="searchChange"
@row-dblclick="rowDblclick"
:before-close="beforeCloseForm"
>
<template #menu-left="{}">
<el-button
type="primary"
icon="el-icon-plus"
@click="proxy.$refs.crudRef.rowAdd()"
v-permission="pageCode + 'add'"
>新增</el-button
>
</template>
<template #menu="{ row, index }">
<el-button
type="primary"
text
icon="el-icon-edit"
@click="proxy.$refs.crudRef.rowEdit(row)"
v-permission="pageCode + 'modify'"
>编辑</el-button
>
<el-popconfirm
title="此操作将删除数据, 是否继续?"
confirm-button-text="删除"
cancel-button-text="取消"
icon="el-icon-delete"
icon-color="red"
@confirm="rowDel(row, index)"
>
<template #reference>
<el-button type="primary" text icon="el-icon-delete" v-permission="pageCode + 'remove'"
>删除</el-button
>
</template>
</el-popconfirm>
</template>
<template #supplierName-form="{}">
<supplier-information-components
v-model="formData.supplierInformationId"
:module-param="moduleParam"
/>
</template>
<template #modelId-form="{}">
<product-model-components v-model="formData.modelId" :module-param="moduleParam" />
</template>
</avue-crud>
</template>
<script setup>
import { ref, getCurrentInstance, reactive } from 'vue'
import supplierInformationComponents from '@/modules/productManagement/components/supplierInformationComponents.vue'
import productModelComponents from '@/modules/productManagement/components/productModelComponents.vue'
//this
let { proxy } = getCurrentInstance()
const option = ref(null)
const data = ref(null)
let queryCondition = ref({})
let formData = ref({})
let moduleParam = reactive({
pageType: 'addOrModify',
entityType: 'supplierProductModel'
})
let pageInfo = reactive({
//
pageNum: 1,
//
pageSize: 10
})
//
let sortInfo = reactive({
sort_field: 'id',
sort_sortType: 'descending'
})
let page = reactive({
total: 0,
currentPage: 1,
pageSize: 10
})
const MODULE_CODE = 'productManagement'
const ENTITY_TYPE = 'supplierProducts'
const pageCode = `${MODULE_CODE}:${ENTITY_TYPE}:`
const api = eval('proxy.$api.' + MODULE_CODE + '.' + ENTITY_TYPE)
option.value = {
dialogWidth: '80%', //
searchMenuSpan: 6, //
addBtn: false, //
editBtn: false, //
delBtn: false, //
column: [
{
label: '产品名称',
labelWidth: 120,
prop: 'productName', //sProductName
search: true,
searchLabelWidth: 120
},
{
label: '产品标识(型号)',
labelWidth: 120,
prop: 'productIdentity',
search: true,
searchLabelWidth: 120
},
{
label: '供应商名称',
labelWidth: 120,
prop: 'supplierName',
type: 'input',
hide: true,
searchLabelWidth: 120,
span: 12
},
{
label: '产品价格',
prop: 'productPrice',
labelWidth: 120,
type: 'number',
precision: 2,
mim: 0
},
{
label: '产品型号',
labelWidth: 120,
prop: 'modelId',
type: 'textarea',
hide: true,
minRows: 4 //
},
{
label: '产品描述',
labelWidth: 120,
prop: 'modelDescription',
//editDisabled: true //
display: false //
},
{
label: '信息来源',
labelWidth: 120,
prop: 'sourceInformation',
hide: true
},
{
label: '备注',
labelWidth: 120,
prop: 'remarks',
hide: true
}
]
}
data.value = []
function rowSave(row, done, loading) {
api
.add(row)
.then((res) => {
done()
onLoad()
})
.catch((err) => {
loading()
})
}
function rowDel(row, index) {
api.remove(row.id)
onLoad()
}
function rowUpdate(row, index, done, loading) {
api
.modify(row)
.then((res) => {
done()
onLoad()
})
.catch((err) => {
loading()
})
}
function onLoad() {
pageInfo.pageNum = page.currentPage
const params = Object.assign(queryCondition.value, pageInfo, sortInfo)
api.page(params).then((res) => {
data.value = res.data.records
page.total = res.data.total
// res.data.total
})
}
function rowDblclick(row, index) {
moduleParam.pageType = 'view'
proxy.$refs.crudRef.rowView(row)
}
//
function beforeCloseForm(done, type) {
done()
moduleParam.pageType = 'addOrModify' //
}
function searchChange(val, done) {
onLoad()
done()
}
</script>
<style>
.el-input,
.el-input-number {
width: 100% !important;
}
</style>

2
src/views/Login/components/LoginForm.vue

@ -56,7 +56,7 @@ const schema = reactive<FormSchema[]>([
{
field: 'password',
label: t('login.password'),
value: '12345678',
value: 'Admin123',
component: 'InputPassword',
colProps: {
span: 24

2
vite.config.ts

@ -112,7 +112,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
}
},
server: {
port: 4000,
port: 3100,
proxy: {
// 选项写法
'/base': {

Loading…
Cancel
Save