Compare commits

...

6 Commits

Author SHA1 Message Date
zhouhaibin 628f5a9ae8 新增产品图片上传 11 months ago
zhouhaibin 51e8829cfa Merge branch 'master' into test 11 months ago
zhouhaibin 59d56975db 新增导出功能 11 months ago
zhouhaibin 8922464fe5 造价管理前端页面优化 11 months ago
zhouhaibin 835a016783 造价管理前端 11 months ago
zhouhaibin 4c89d00851 产品管理初步代码提交 12 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. 228
      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. 205
      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. 106
      src/modules/productManagement/components/uploadImage.vue
  19. 273
      src/modules/productManagement/view/companyProducts/index.vue
  20. 266
      src/modules/productManagement/view/personProducts/index.vue
  21. 167
      src/modules/productManagement/view/productModelTemplate/index.vue
  22. 69
      src/modules/productManagement/view/supplierInformation/add.vue
  23. 148
      src/modules/productManagement/view/supplierInformation/index.vue
  24. 69
      src/modules/productManagement/view/supplierInformation/modify.vue
  25. 55
      src/modules/productManagement/view/supplierInformation/view.vue
  26. 279
      src/modules/productManagement/view/supplierProducts/index.vue
  27. 4
      src/modules/support/api/index.ts
  28. 2
      src/views/Login/components/LoginForm.vue
  29. 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 })
},
// 导出数据
exportData(id) {
return request.download({ url: this.serveUrl + 'exportData/'+id })
}
})
// 造价明细
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' + '/'
})

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

@ -0,0 +1,228 @@
<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
},
productSpecifications: {
label: '产品描述',
labelWidth: 120,
//editDisabled: true //
display: false ,//,
overHidden: true,
},
image: {
label: '图片',
labelWidth: 120,
type: 'upload'
},
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.productSpecifications
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>

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

@ -0,0 +1,205 @@
<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>
<el-button
type="primary"
text
icon="el-icon-download"
@click="exportData(row)"
v-permission="pageCode + 'remove'"
>导出</el-button
>
</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()
}
function exportData(row) {
api.exportData(row.id)
}
</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.productSpecifications
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>

106
src/modules/productManagement/components/uploadImage.vue

@ -0,0 +1,106 @@
<template>
<el-upload
v-model:file-list="fileList"
class="upload-demo"
action
:on-preview="handlePreview"
:on-remove="handleRemove"
list-type="picture"
:limit="1"
:http-request="ImgUploadSectionFile"
:before-upload="beforeAvatarUpload"
:on-change="handleEditChange"
:on-exceed="handleExceed"
accept=".png, .jpg"
>
<el-button type="primary">上传图片</el-button>
<template #tip>
<div class="el-upload__tip">支持 jpg/png 最大尺寸为10Mb</div>
</template>
</el-upload>
<el-dialog v-model="dialogVisible">
<img w-full :src="dialogImageUrl" alt="Preview Image" />
</el-dialog>
</template>
<script lang="ts" setup>
import { ref,defineEmits,defineProps} from 'vue'
import { ElMessage } from 'element-plus'
import type { UploadProps, UploadUserFile } from 'element-plus'
const propsData= defineProps(["modelValue","moduleParam"])
const emits= defineEmits(['update:modelValue'])
const fileList = ref<UploadUserFile[]>([])
let dialogVisible = ref(false)
let dialogImageUrl = ref()
if(propsData.modelValue){
fileList.value.push({url:propsData.modelValue,name:propsData.modelValue.split('/')[propsData.modelValue.split('/').length-1]})
console.log(fileList.value)
}
// const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
// console.log(uploadFile, uploadFiles)
// }
const handlePreview: UploadProps['onPreview'] = (file) => {
console.log(file)
dialogImageUrl.value = file.url
dialogVisible.value = true
}
//
function handleRemove(file, fileList) {
if (fileList.length === 0) {
fileList = []
} else {
let dl = fileList.indexOf(file)
fileList.splice(dl, 1)
}
console.log('remove', file, fileList)
// hideUploadEdit = fileList.length >= limitNum
}
// on-change
function handleEditChange(file, fileList) {
console.log('file:', file, fileList)
// hideUploadEdit = fileList.length >= limitNum
// console.log("this.fileList:", this.fileList);
// console.log("this.hideUploadEdit:", this.hideUploadEdit);
}
// http-request
function ImgUploadSectionFile(param) {
console.log('param', param)
emits("update:modelValue",param.file)
}
// before-upload
// false Promise reject
function beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
const isLt2M = file.size / 1024 / 1024 < 10
if (!isJPG) {
ElMessage.error('上传图片只能是 JPG 或 PNG 格式!')
}
if (!isLt2M) {
ElMessage.error('上传图片大小不能超过 10MB!')
}
return isJPG && isLt2M
}
function handleExceed() {
ElMessage.warning('最多只能上传一个文件')
}
</script>
<!-- :limit="limitNum" //
:class="{hide:hideUploadEdit}" //
:on-remove="handleRemove" //
:on-change="handleEditChange" //()
:http-request="ImgUploadSectionFile" //
:before-upload="beforeAvatarUpload" //
:with-credentials="true" // cookie
:auto-upload="true" //(false)
accept=".png, .jpg" //
action="" //url
list-type="picture-card" //
:file-list="fileList" //
-->

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

@ -0,0 +1,273 @@
<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>
<template #image-form="{}">
<uploadImage v-model="formData.image" :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'
import uploadImage from '@/modules/productManagement/components/uploadImage.vue'
import apiIndex from '@/api/index'
//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,
html: true,
formatter: (val) => {
return val.productName
},
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: 'productSpecifications',
//editDisabled: true //
html: true,
formatter: (val) => {
return val.productSpecifications
},
display: false //
},
{
label: '图片',
labelWidth: 120,
prop: 'image',
type: 'img'
// httpRequest: (file, column) => {
// console.log("image",file, column)
// const formData = new FormData()
// formData.append('image', file.file)
// apiIndex.support.attachment.uploadImageReturnUrl(formData)
// }
},
{
label: '品牌',
labelWidth: 120,
prop: 'brand'
},
{
label: '单位',
labelWidth: 120,
prop: 'unit'
},
{
label: '除税价格',
labelWidth: 120,
prop: 'exTaxPrice'
},
{
label: '税率',
labelWidth: 120,
prop: 'taxrate'
},
{
label: '信息来源',
labelWidth: 120,
prop: 'sourceInformation',
hide: true
},
{
label: '备注',
labelWidth: 120,
prop: 'remarks',
hide: true
}
]
}
data.value = []
async function rowSave(row, done, loading) {
// url
console.log(row.image)
const formData = new FormData()
formData.append('image', row.image)
let res = await apiIndex.support.attachment.uploadImageReturnUrl(formData)
row.image = res.data
//
api
.add(row)
.then(() => {
done()
onLoad()
})
.catch(() => {
loading()
})
}
function rowDel(row, index) {
api.remove(row.id)
onLoad()
}
async function rowUpdate(row, index, done, loading) {
if (typeof row.image === 'object') {
console.log(row.image)
const formData = new FormData()
formData.append('image', row.image)
let res = await apiIndex.support.attachment.uploadImageReturnUrl(formData)
row.image = res.data
}
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>

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

@ -0,0 +1,266 @@
<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>
<template #image-form="{}">
<uploadImage v-model="formData.image" :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'
import apiIndex from '@/api/index'
import uploadImage from '@/modules/productManagement/components/uploadImage.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,
html: true,
formatter: (val) => {
return val.productName
},
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: 'productSpecifications',
//editDisabled: true //
html: true,
formatter: (val) => {
return val.productSpecifications
},
display: false //
},
{
label: '图片',
labelWidth: 120,
prop: 'image',
type: 'img'
},
{
label: '品牌',
labelWidth: 120,
prop: 'brand'
},
{
label: '单位',
labelWidth: 120,
prop: 'unit'
},
{
label: '除税价格',
labelWidth: 120,
prop: 'exTaxPrice'
},
{
label: '税率',
labelWidth: 120,
prop: 'taxrate'
},
{
label: '信息来源',
labelWidth: 120,
prop: 'sourceInformation',
hide: true
},
{
label: '备注',
labelWidth: 120,
prop: 'remarks',
hide: true
}
]
}
data.value = []
async function rowSave(row, done, loading) {
if (typeof row.image === 'object') {
console.log(row.image)
const formData = new FormData()
formData.append('image', row.image)
let res = await apiIndex.support.attachment.uploadImageReturnUrl(formData)
row.image = res.data
}
api
.add(row)
.then(() => {
done()
onLoad()
})
.catch(() => {
loading()
})
}
function rowDel(row, index) {
api.remove(row.id)
onLoad()
}
async function rowUpdate(row, index, done, loading) {
if (typeof row.image === 'object') {
console.log(row.image)
const formData = new FormData()
formData.append('image', row.image)
let res = await apiIndex.support.attachment.uploadImageReturnUrl(formData)
row.image = res.data
}
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>

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

@ -0,0 +1,279 @@
<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>
<template #image-form="{}">
<uploadImage v-model="formData.image" :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'
import apiIndex from '@/api/index'
import uploadImage from '@/modules/productManagement/components/uploadImage.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,
// overHidden: true,
html:true,
formatter:(val)=>{
return val.productName
},
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: 'productSpecifications',
search: true,
//editDisabled: true //
// overHidden: true,
html:true,
formatter:(val)=>{
return val.productSpecifications
},
display: false //
},
{
label: '图片',
labelWidth: 120,
prop: 'image',
type: 'upload',
},
{
label: '品牌',
labelWidth: 120,
prop: 'brand',
},
{
label: '单位',
labelWidth: 120,
prop: 'unit',
},
{
label: '除税价格',
labelWidth: 120,
prop: 'exTaxPrice',
},
{
label: '税率',
labelWidth: 120,
prop: 'taxrate',
},
{
label: '信息来源',
labelWidth: 120,
prop: 'sourceInformation',
hide: true
},
{
label: '备注',
labelWidth: 120,
prop: 'remarks',
hide: true
}
]
}
data.value = []
async function rowSave(row, done, loading) {
if (typeof row.image === 'object') {
console.log(row.image)
const formData = new FormData()
formData.append('image', row.image)
let res = await apiIndex.support.attachment.uploadImageReturnUrl(formData)
row.image = res.data
}
api
.add(row)
.then((res) => {
done()
onLoad()
})
.catch((err) => {
loading()
})
}
function rowDel(row, index) {
api.remove(row.id)
onLoad()
}
async function rowUpdate(row, index, done, loading) {
if (typeof row.image === 'object') {
console.log(row.image)
const formData = new FormData()
formData.append('image', row.image)
let res = await apiIndex.support.attachment.uploadImageReturnUrl(formData)
row.image = res.data
}
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>

4
src/modules/support/api/index.ts

@ -54,6 +54,10 @@ export const attachment = Object.assign({}, COMMON_METHOD, {
// 上传图片
uploadImage(param) {
return request.upload({ url: this.serveUrl + 'uploadImage', data: param })
},
uploadImageReturnUrl(param){
return request.upload({ url: this.serveUrl + 'uploadImageReturnUrl', data: param })
}
})

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

@ -63,7 +63,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