hi-ucs/front/src/views/capacityOnTheShelf/components/PutOnTheShelf.vue

1031 lines
29 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: hisense.liangjunhua
* @Date: 2022-06-17 14:11:08
* @LastEditors: hisense.wuhongjian
* @LastEditTime: 2022-07-16 15:05:16
* @Description: 上架
-->
<template>
<div class="put-on-the-shelf">
<div v-for="title in props.refData.children" :key="title.id">
<div class="top">
<div></div>
<div>{{ title.name }}</div>
<div></div>
</div>
<template v-if="title.isConfigure">
<div class="bottom">
<div class="items" v-if="data[title.name].length > 0">
<div
class="item"
v-for="(val, index) in data[title.name]"
:key="'key1' + val.name + index"
>
<p>
<span>{{ title.name }}-{{ index + 1 }}</span>
<span></span>
</p>
<p
v-for="attr in props.configure.filter(
(item, index2) => item.name === title.name
)[0].list"
:key="'key2' + attr.name + index2"
>
<span>{{ attr.name }}</span>
<span v-if="attr.type === 'image'">
<a-image :width="85" :height="60" :src="val.img" />
</span>
<span v-else>{{ val[attr.field] + (attr.company || '') }}</span>
</p>
<div class="del">
<i class="delImg" @click="del(title.name, index)"></i>
<div @click="del(title.name, index)">删除</div>
</div>
</div>
</div>
<div class="add">添加更多{{ title.name }}</div>
<div
class="form"
v-for="(val, index) in props.configure.filter(
(item) => item.name === title.name
)[0].list"
:key="'key3' + val.name + index"
>
<span>{{ val.name }}</span>
<a-input
v-model:value="val.note1"
:maxlength="24"
:placeholder="'请填写' + val.name + ',不超过24个字符'"
v-if="val.type == 'input'"
/>
<template v-if="val.type == 'input2'">
<a-input
v-model:value="val.note1"
:placeholder="'请填写' + val.name"
/>
<span style="width: 0.5rem; padding-left: 0.1rem">
{{
numType == '一次性买断'
? '元'
: numType == '按调用次数'
? '元/次'
: numType == '按并发路数'
? '元/路'
: numType == '按年计费'
? '元/年'
: ''
}}
</span>
</template>
<a-textarea
v-model:value="val.note1"
:showCount="true"
:maxlength="200"
:placeholder="'请填写' + val.name"
v-else-if="val.type == 'textArea'"
/>
<a-input-number
v-model:value="val.note1"
:min="0"
:max="9999"
:step="0.01"
string-mode
:placeholder="'请填写' + val.name"
v-else-if="val.type == 'number'"
/>
<a-radio-group
v-model:value="val.note1"
:options="val.options"
@change="radioChange"
v-else-if="val.type == 'radio'"
/>
<upload
:key="showKey"
type="图片"
btnName="上传图片"
:maxCount="1"
:data="val"
:list="[]"
tip="支持图片类型大小不超过100M"
v-else-if="val.type == 'image'"
></upload>
</div>
<div class="submit">
<a-button type="primary" @click="add(title.name)">
添加更多
</a-button>
</div>
</div>
</template>
<template v-else>
<div class="bottom">
<div
class="form"
v-for="item in title.children"
:key="item.id"
v-show="
!(
(showType == '调用接口' && item.name == '平台地址') ||
(showType == '调用接口' && item.name == 'SDK安装包') ||
(showType == '平台对接' && item.name == 'SDK安装包') ||
(showType == '平台对接' && item.name == '接口请求方式') ||
(showType == '平台对接' && item.name == '服务接口') ||
(showType == 'SDK' && item.name == '平台地址') ||
(showType == 'SDK' && item.name == '接口请求方式') ||
(showType == 'SDK' && item.name == '服务接口')
)
"
>
<span>{{ item.name }}</span>
<a-input
v-if="item.type == 'input'"
v-model:value="item.note1"
:placeholder="'请输入' + item.name"
/>
<a-radio-group
v-else-if="item.type == 'radio'"
v-model:value="item.note1"
:options="item.options"
/>
<a-input
v-else-if="item.type == 'AbilityType'"
v-model:value="item.note1"
:placeholder="'请输入' + item.name"
:disabled="true"
/>
<a-input
v-else-if="item.type == 'ComponentType'"
v-model:value="item.note1"
:placeholder="'请输入' + item.name"
:disabled="true"
/>
<a-textarea
v-else-if="item.type == 'textArea'"
v-model:value="item.note1"
:showCount="true"
:maxlength="200"
:placeholder="'请输入' + item.name"
/>
<upload
v-else-if="item.type == 'image'"
type="图片"
btnName="上传图片"
:maxCount="1"
:data="item"
:list="props.imgList"
tip="支持图片类型大小不超过100M"
></upload>
<upload
v-else-if="item.type == 'file' && item.name !== '使用手册'"
type="文件"
btnName="上传附件"
:maxCount="1"
:data="item"
:list="props.fileList"
tip="支持文件类型大小不超过100M"
></upload>
<upload
v-else-if="item.name == '使用手册'"
type="文件"
btnName="上传附件"
:maxCount="1"
:data="item"
:busType="2"
:list="props.fileList2"
tip="支持文件类型大小不超过100M"
></upload>
<upload
v-else-if="item.type == 'package'"
type="压缩包"
btnName="上传安装包"
:maxCount="1"
:data="item"
:list="props.packageList"
tip="支持.zip类型"
></upload>
<div
class="Technical-text"
v-else-if="item.type == 'richText'"
@click="showTextFunction()"
>
编辑富文本
<div
v-if="showText"
class="fuwenbenbianjiqi"
style="position: absolute; z-index: 10000"
>
<VueTemplateDemo :dataFrom="props.dataFrom"></VueTemplateDemo>
</div>
</div>
<upload
v-else-if="item.type == 'video'"
type="视频"
btnName="上传视频"
:maxCount="1"
:data="item"
:list="props.videoList"
tip="支持视频类型大小不超过100M"
></upload>
<a-button
v-else-if="item.type == 'AssociatedApplication'"
@click="sourceClick"
>
请选择来源应用
</a-button>
<a-button
v-else-if="item.type == 'AssociatedComponents'"
@click="componentsClick"
>
请选择关联组件
</a-button>
<a-select
v-else-if="item.type == 'select' && item.name == '使用方式'"
style="width: 240px"
v-model:value="item.note1"
:placeholder="'请选择' + item.name"
@change="showTypeClick"
>
<a-select-option
v-for="(itemSelect, indexSelect) in item.options"
:key="indexSelect"
:value="itemSelect.dictLabel"
>
{{ itemSelect.dictLabel }}
</a-select-option>
</a-select>
<a-select
v-else-if="item.type == 'select' && item.name !== '归属部门'"
style="width: 240px"
v-model:value="item.note1"
:placeholder="'请选择' + item.name"
>
<a-select-option
v-for="(itemSelect, indexSelect) in item.options"
:key="indexSelect"
:value="itemSelect.dictLabel"
>
{{ itemSelect.dictLabel }}
</a-select-option>
</a-select>
<a-select
v-else-if="item.name === '归属部门'"
style="width: 240px"
v-model:value="item.note1"
show-search
placeholder="请输入关键字"
:options="item.options"
:filter-option="filterOption"
@focus="handleFocus"
@blur="handleBlur"
@change="handleChange2"
></a-select>
<div
v-else-if="item.type == 'checkBox'"
class="application-Area"
id="application-Area"
:key="showKey"
>
<div
v-for="(itemson, indexson) in item.options"
:key="indexson"
class="application-Area-son"
@click="ApplicationArea(item, itemson)"
:class="
item.note2.indexOf(itemson.dictLabel) != -1
? 'application-Area-down'
: ''
"
>
{{ itemson.dictLabel }}
</div>
</div>
</div>
<div class="AssociatedApplication">
<a-modal
v-model:visible="visibleAssociatedApplication"
:title="titleName"
@ok="handleOk"
@cancel="handleCancel"
style="width: 960px"
>
<div>
<a-transfer
v-model:target-keys="targetKeys"
v-model:selected-keys="selectedKeys"
:data-source="mockData"
:titles="titles"
:render="(item) => item.title"
@change="handleChange"
@selectChange="handleSelectChange"
/>
</div>
</a-modal>
</div>
</div>
</template>
</div>
</div>
</template>
<script setup>
import { ref, defineProps, watch, onMounted } from 'vue'
import mybus from '@/myplugins/mybus'
import upload from '@/views/components/upload'
import { message } from 'ant-design-vue'
import { getUserInfo, getDeptAll } from '@/api/user'
import {
getCategoryTreePage,
queryApplicationRelByResourceId,
queryResourceRelByKeyId,
filesUpload,
} from '@/api/personalCenter'
import VueTemplateDemo from '@/views/personalCenter/VueTemplateDemo.vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const abilityToType = router.currentRoute.value.query.abilityToType
const componentTypeValue = router.currentRoute.value.query.componentTypeValue
const props = defineProps({
// 展示数据
refData: { type: Object, default: null },
// 表单数据
dataFrom: { type: Array, default: null },
// 文件回显
fileList: { type: Array, default: null },
fileList2: { type: Array, default: null },
// 压缩包回显
packageList: { type: Array, default: null },
// 图片回显
imgList: { type: Array, default: null },
// 视频回显
videoList: { type: Array, default: null },
// 外部字段
externalField: { type: Array, default: null },
// 多条的配置
configure: { type: Array, default: null },
// [{
// name:'计费标准信息',
// list:[
// {
// name:'计费方式',
// type:'radio',
// field:'type',
// options:
// {
// name:'一次性买断',
// value:'1'
// },
// {
// name:'按调用次数',
// value:'2'
// },
// {
// name:'按并发路数',
// value:'3'
// },
// {
// name:'按年计费',
// value:'4'
// }
// ],
// note1:''
// },
// {
// name:'计费标准',
// field:'price',
// type:'number',
// company:'元',
// note1: ''
// },
// {
// name:'计费标准描述',
// field:'desc',
// type:'textArea',
// note1:''
// }
// ]
// }]
})
// console.log('props==========>', props)
const changeAdd = () => {
console.log('子组件方法触发~')
}
const data = ref({
list: [],
})
const showKey = ref(0)
const numType = ref('一次性买断')
const radioChange = (e) => {
numType.value = e.target.value
}
props.refData.children.map((item) => {
if (item.name == '基本信息') {
item.children.map((val) => {
if (val.name == '能力类型') {
val.note1 = abilityToType
}
if (val.name == '组件类型') {
val.note1 = componentTypeValue
}
})
}
if (
props.configure &&
props.configure.filter((val) => val.name === item.name).length > 0
) {
item.isConfigure = true
data.value[item.name] = []
} else {
item.isConfigure = false
}
})
let arr = props.refData.children.filter((item) => {
if (props.configure) {
if (!item.isConfigure) {
return item
}
} else {
return item
}
})
data.value.list = []
// 获取字典数据
arr.forEach((val) => {
val.children.forEach((item) => {
if (item.isLinkToDic === 'true' && item.linkValue) {
getCategoryTreePage({
page: 1,
limit: 20,
dictTypeId: item.linkValue,
deFlage: 0,
}).then((res) => {
if (item.type === 'radio') {
item.options = res.data.data.list.map((radio) => radio.dictLabel)
} else if (item.type === 'select' || item.type === 'checkBox') {
if (item.type === 'checkBox') {
if (!item.note2) {
item.note2 = []
}
}
item.options = res.data.data.list
}
data.value.list.push(item)
})
} else if (item.name === '归属部门') {
getDeptAll().then((res) => {
const dataList = []
res.data.data.forEach((element) => {
dataList.push({
value: element.id,
label: element.name,
})
})
item.options = dataList
if (!item.note1) {
getUserInfo().then(({ data: res1 }) => {
console.log(res1.data)
item.note1 = res1.data.deptId
console.log('默认部门=========>', item, res1.data)
data.value.list.push(item)
})
}
})
} else {
data.value.list.push(item)
}
})
})
if (props.dataFrom) {
// console.log(props.dataFrom, data.value.list)
props.dataFrom.infoList.forEach((item) => {
if (
props.configure &&
props.configure.filter((val) => val.name === item.attrType).length > 0
) {
data.value[item.attrType] = JSON.parse(item.attrValue)
} else if (item.attrType === '应用领域') {
props.refData.children.forEach((val) => {
val.children.forEach((child) => {
if (child.name === item.attrType) {
// 通过;分割成数组
child.note2 = item.attrValue.split(';')
showKey.value++
// console.log('应用领域', item, item.attrValue.split(';'), child)
}
})
})
// item.note1 = item.attrValue.split(';')
}
})
}
//显示富文本
let showText = ref(false)
const showTextFunction = () => {
showText.value = true
}
mybus.on('showTextFunctionEmit', (show) => {
console.log('ssdcsd')
debugger
showText.value = show
})
mybus.off('func')
const add = (title) => {
console.log(title, 'title')
let list = props.configure.filter((item) => item.name === title)[0].list
let flag = true
list.forEach((item) => {
// console.log(item)
if (item.type !== 'number' && !item.note1.length > 0) {
flag = false
} else if (item.type === 'number' && !item.note1 > 0) {
flag = false
}
})
if (flag) {
let obj = {}
list.forEach((item) => {
if (item.type === 'input2') {
obj[item.field] =
item.note1 +
(numType.value == '一次性买断'
? '元'
: numType.value == '按调用次数'
? '元/次'
: numType.value == '按并发路数'
? '元/路'
: numType.value == '按年计费'
? '元/年'
: '')
} else {
obj[item.field] = item.note1
}
})
data.value[title].push(obj)
// console.log(data.value[title])
mybus.emit('chageDataFrom', {
attrType: title,
attrValue: JSON.stringify(data.value[title]),
delFlag: 0,
})
list.forEach((item) => {
item.note1 = ''
showKey.value++
})
} else {
message.warning('请填写完整')
}
}
const del = (title, index) => {
data.value[title].splice(index, 1)
mybus.emit('chageDataFrom', {
attrType: title,
attrValue: JSON.stringify(data.value[title]),
delFlag: 0,
})
}
const ApplicationArea = (item, itemson) => {
console.log('点击=========》', item, itemson)
// console.log(item, itemson)
if (item.note2.indexOf(itemson.dictLabel) === -1) {
item.note2.push(itemson.dictLabel)
} else {
item.note2.splice(item.note2.indexOf(itemson.dictLabel), 1)
}
mybus.emit('chageDataFrom', {
attrType: item.name,
attrValue: item.note2.join(';'),
delFlag: 0,
})
}
// 来源应用
const visibleAssociatedApplication = ref(false)
const mockData = ref([])
const titles = ref(['未关联的应用名称', '已关联的应用名称'])
const titleName = ref('关联应用')
const targetKeys = ref([])
// 上一步关联数据
const targetKeysBack = ref([])
const sourceClick = () => {
mockData.value = []
visibleAssociatedApplication.value = true
props.dataFrom.infoList.forEach((val) => {
if (val.attrType === '来源应用' && val.attrValue != '') {
queryApplicationRelByResourceId({
referenceId: 0,
}).then((res) => {
// console.log(res.data.data.notLinked)
res.data.data.notLinked.forEach((val, index) => {
mockData.value.push({
key: val.id,
title: val.name,
description: val.id,
})
})
})
targetKeys.value = []
val.attrValue.split(',').forEach((item) => {
targetKeys.value.push(item)
})
console.log(targetKeys.value)
// console.log('wowowo')
} else if (val.attrType === '来源应用' && val.attrValue == '') {
queryApplicationRelByResourceId({
referenceId: 0,
}).then((res) => {
// console.log(res.data.data.notLinked)
res.data.data.notLinked.forEach((val, index) => {
mockData.value.push({
key: val.id,
title: val.name,
description: val.id,
})
})
})
}
})
}
// 关联组件
const componentsClick = () => {
titles.value = ['未关联的组件名称', '已关联的组件名称']
titleName.value = '关联组件'
mockData.value = []
visibleAssociatedApplication.value = true
props.dataFrom.infoList.forEach((val) => {
if (val.attrType === '关联组件信息' && val.attrValue != '') {
queryResourceRelByKeyId({
keyId: 0,
type: '组件服务',
referenceName: '',
}).then((res) => {
// console.log(res.data.data.notLinked)
res.data.data.notLinked.forEach((val, index) => {
mockData.value.push({
key: val.id,
title: val.name,
description: val.id,
})
})
})
targetKeys.value = []
val.attrValue.split(',').forEach((item) => {
targetKeys.value.push(item)
})
console.log(targetKeys.value)
// console.log('wowowo')
} else if (val.attrType === '关联组件信息' && val.attrValue == '') {
queryResourceRelByKeyId({
keyId: 0,
type: '组件服务',
referenceName: '',
}).then((res) => {
// console.log(res.data.data.notLinked)
res.data.data.notLinked.forEach((val, index) => {
mockData.value.push({
key: val.id,
title: val.name,
description: val.id,
})
})
})
}
})
}
const selectedKeys = ref([])
const handleChange = (nextTargetKeys, direction, moveKeys) => {
console.log('targetKeys: ', nextTargetKeys)
console.log('direction: ', direction)
console.log('moveKeys: ', moveKeys)
targetKeys.value = moveKeys
}
const handleSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
console.log('targetSelectedKeys: ', targetSelectedKeys, sourceSelectedKeys)
}
const handleOk = (e) => {
console.log(e)
visibleAssociatedApplication.value = false
// console.log('2222222222222', props.refData)
data.value.list.map((item) => {
if (item.name === '来源应用' || item.name === '关联组件信息') {
item.note1 = targetKeys.value + ''
}
})
}
const handleCancel = (e) => {
console.log(e)
visibleAssociatedApplication.value = false
}
const showType = ref('')
const showTypeClick = (e) => {
showType.value = e
console.log(e, 'showType', showType.value)
}
showTypeClick('调用接口')
watch(data.value.list, (newProps, oldProps) => {
// console.log(newProps, oldProps)
newProps.forEach((val) => {
// console.log('数据发生改变==========>', val)
if (
props.configure &&
props.configure.filter((item) => item.name === val.name).length > 0
) {
mybus.emit('chageDataFrom', {
attrType: val.name,
attrValue: val.note1,
delFlag: 0,
})
} else if (
props.externalField &&
props.externalField.indexOf(val.name) > -1
) {
mybus.emit('chageDataFromDwon', {
attrType: val.name,
attrValue: val.note1,
delFlag: 0,
})
} else {
if (val.name !== '应用领域' && val.name !== '发布端') {
mybus.emit('chageDataFrom', {
attrType: val.name,
attrValue: val.note1,
delFlag: 0,
})
}
}
})
})
const handleChange2 = (value) => {
console.log(`selected ${value}`)
}
const handleBlur = () => {
console.log('blur')
}
const handleFocus = () => {
console.log('focus')
}
const filterOption = (input, option) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
</script>
<style></style>
<style lang="less" scoped>
.put-on-the-shelf {
height: 680px;
overflow: scroll;
display: flex;
flex-direction: column;
align-items: center;
padding: 50px 100px 25px;
.Technical-text {
height: 30px;
width: 100px;
border: 1px solid #bbd3ef;
border-radius: 6px;
background: #edf4fc;
color: #0087ff;
font-size: 14px;
text-align: center;
line-height: 30px;
}
.Technical-text:hover {
cursor: pointer;
}
& > div {
width: 100%;
margin-top: 60px;
.top {
color: #333333;
font-size: 22px;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 25px;
div:first-child,
div:last-child {
width: 245px;
height: 1px;
background: #f0f0f0;
}
div:nth-child(2) {
margin: 0 30px;
}
}
.bottom {
margin-top: 25px;
.items {
background: #fafafa;
padding: 10px;
p {
display: flex;
justify-content: space-between;
span:nth-of-type(1) {
width: 200px;
}
span:nth-of-type(2) {
width: 100%;
font-weight: 600;
}
}
p:nth-of-type(1) > span:nth-of-type(1) {
font-size: 18px;
font-weight: 600;
}
.del {
display: flex;
justify-content: flex-end;
align-items: center;
.delImg {
cursor: pointer;
display: inline-block;
width: 16px;
height: 18px;
background: url(~@/assets/home/sf_del.png) no-repeat;
margin-right: 5px;
}
div {
cursor: pointer;
}
}
}
.add {
margin-top: 10px;
font-size: 16px;
color: #007efb;
}
.form {
margin-top: 20px;
display: flex;
justify-content: flex-start;
align-items: center;
span:first-child {
width: 120px;
}
:deep(.ant-input-textarea) {
width: 520px;
}
:deep(.ant-radio-group) {
width: 520px;
}
:deep(.ant-input-number) {
width: 200px;
}
:deep(.ant-input) {
resize: none;
width: 520px;
}
.ant-btn {
width: 160px;
height: 32px;
text-align: center;
background: #edf4fc;
color: #0087ff;
border: 1px solid #bbd3ef;
border-radius: 6px;
}
}
.submit {
margin-top: 40px;
display: flex;
justify-content: flex-end;
.ant-btn {
width: 80px;
height: 28px;
text-align: center;
background: #d9ebff;
color: #0087ff;
border: 1px solid #0087ff;
border-radius: 6px;
}
}
}
}
& > div:nth-of-type(1) {
margin-top: 0;
}
}
.application-Area {
width: 520px;
display: grid;
margin-top: -5px;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
.application-Area-son {
cursor: pointer;
font-size: 14px;
width: 90px;
height: 26px;
border-radius: 13px;
color: #333333;
background: #f5f5f5;
border: 1px #cccccc solid;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
font-weight: 500;
}
.application-Area-down {
background: #0087ff;
color: #fff;
}
}
:deep(.ant-image-img) {
width: 100%;
height: 100%;
object-fit: contain;
}
:deep(.ant-modal) {
width: 960px;
}
:deep(.ant-transfer-list) {
width: 39.5%;
height: 520px;
}
:deep(.ant-transfer-operation) {
flex-direction: row-reverse;
margin: 0 30px;
}
:deep(.ant-btn) {
width: 56px;
height: 40px;
border-radius: 4px;
}
:deep(.ant-btn:first-child) {
margin-left: 4px;
}
:deep(.ant-modal-footer) {
border: 0;
}
:deep(.ant-modal-header) {
border: 0;
}
:deep(.ant-modal-title) {
line-height: 24px;
font-size: 18px;
color: #303133;
}
:deep(.ant-transfer-list-header) {
background: #f5f7fa;
}
:deep(.ant-transfer-list-header-selected) {
display: flex;
width: 90%;
flex-direction: row-reverse;
justify-content: space-between;
align-items: center;
}
:deep(.ant-transfer-list-header-title) {
font-size: 16px;
color: #303133;
font-weight: 400;
text-align: left;
}
:deep(.ant-transfer-list-header .ant-checkbox-wrapper) {
display: none !important;
}
</style>