|
@@ -1,141 +1,182 @@
|
|
|
<template>
|
|
|
<div class='app-container'>
|
|
|
<el-form class="form" label-width="100px" ref="form" :model="data.form" :rules="data.rules">
|
|
|
- <el-form-item class="audioList" label="选择音频:">
|
|
|
- <el-tag v-for="item in data.form.audioList" :key="item.audioId" size="large" closable>
|
|
|
- {{ item.audioName }}
|
|
|
- </el-tag>
|
|
|
- <div class="audio">
|
|
|
- <img src="@/assets/icons/svg/file.svg" width="70" height="70" />
|
|
|
- <span>双十一活动</span>
|
|
|
- <span>3小时21分</span>
|
|
|
+ <el-form-item class="chooseAudio" label="选择音频:" prop="audioList">
|
|
|
+ <div class="audioList" v-for="item in data.form.audioList" :key="item.id">
|
|
|
+ <el-tag v-show="item.type === 0 || item.type === 1" size="large" closable @close="handleClose(item)">
|
|
|
+ {{ item.audioName }}
|
|
|
+ </el-tag>
|
|
|
+ <div v-show="item.type === 2" class="audio">
|
|
|
+ <img src="@/assets/icons/svg/file.svg" width="70" height="70" />
|
|
|
+ <span>{{ item.audioName }}</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<el-button icon="Plus" @click="getDialog">新增</el-button>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="内容名称:">
|
|
|
+ <el-form-item label="内容名称:" prop="name">
|
|
|
<el-input v-model="data.form.name" placeholder="请输入内容名称" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="播放时间:">
|
|
|
+ <el-form-item label="播放时间:" prop="listDate">
|
|
|
<div class="date" v-for="(item, index) in data.dateList">
|
|
|
- <el-date-picker type="datetimerange" start-placeholder="开始时间" end-placeholder="结束时间"
|
|
|
- format="YYYY-MM-DD HH:mm:ss" date-format="YYYY/MM/DD ddd" time-format="A hh:mm:ss" />
|
|
|
+ <el-date-picker v-model="data.dateList[index]" type="datetimerange" start-placeholder="开始时间"
|
|
|
+ end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ @change="handleChangeDate($event, index)" />
|
|
|
<el-link v-show="data.dateList.length > 1" icon="CircleClose" :underline="false"
|
|
|
@click="handleDeleteDate(index)" />
|
|
|
<el-link v-show="data.dateList.length - 1 === index" icon="CirclePlus" :underline="false"
|
|
|
@click="handlePushDate" />
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="所属门店:" style="width: 800px">
|
|
|
- <el-table :data="data.form.list">
|
|
|
- <el-table-column label="所属" align="center">
|
|
|
+ <el-form-item label="所属门店:" style="width: 900px">
|
|
|
+ <el-table :data="data.form.tpresetContentInfoReq">
|
|
|
+ <el-table-column label="所属企业" align="center">
|
|
|
<template #default="scope">
|
|
|
- <el-select>
|
|
|
- <!-- <el-option /> -->
|
|
|
- </el-select>
|
|
|
+ <el-form-item :prop="`tpresetContentInfoReq.${scope.$index}.tenantId`"
|
|
|
+ :rules="{ required: true, trigger: 'change' }">
|
|
|
+ <el-select v-model="scope.row.tenantId" placeholder="请选择企业" style="width: 200px" filterable remote
|
|
|
+ :remote-method="businessRemote" remote-show-suffix @change="handleChange">
|
|
|
+ <el-option v-for="item in businessData.options" :key="item.id" :value="item.id" :label="item.name" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="所属门店" align="center">
|
|
|
<template #default="scope">
|
|
|
- <el-select>
|
|
|
- <!-- <el-option /> -->
|
|
|
- </el-select>
|
|
|
+ <el-form-item :prop="`tpresetContentInfoReq.${scope.$index}.storeId`"
|
|
|
+ :rules="{ required: true, trigger: 'change' }">
|
|
|
+ <el-select v-model="scope.row.storeId" placeholder="请选择门店" style="width: 200px" filterable remote
|
|
|
+ :remote-method="storeRemote" remote-show-suffix>
|
|
|
+ <el-option v-for="item in storeData.options" :key="item.id" :value="item.id" :label="item.name" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="所属设备" align="center">
|
|
|
<template #default="scope">
|
|
|
- <el-select>
|
|
|
- <!-- <el-option /> -->
|
|
|
- </el-select>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="操作" align="center">
|
|
|
- <template #default="scope">
|
|
|
- <el-button type="danger" link>删除</el-button>
|
|
|
+ <el-form-item :prop="`tpresetContentInfoReq.${scope.$index}.deviceType`"
|
|
|
+ :rules="{ required: true, trigger: 'change' }">
|
|
|
+ <el-select v-model="scope.row.deviceType" filterable placeholder="请选择所属设备">
|
|
|
+ <el-option v-for="item in deviceOptions" :key="item.clientTypeId" :value="item.clientTypeId"
|
|
|
+ :label="item.name" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
</el-form-item>
|
|
|
<el-form-item style="width: 800px">
|
|
|
- <el-button icon="Plus">新增关联</el-button>
|
|
|
+ <el-button icon="Plus" @click="getAdd">新增关联</el-button>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
<div class="form-btn">
|
|
|
<el-button @click="getClose">取消</el-button>
|
|
|
- <el-button type="primary">确定</el-button>
|
|
|
+ <el-button type="primary" @click="getSubmit">确定</el-button>
|
|
|
</div>
|
|
|
|
|
|
- <el-dialog v-model="dialogVisible" title="导入内容">
|
|
|
+ <el-dialog v-model="dialogVisible" title="导入内容" width="1000px">
|
|
|
<el-form inline>
|
|
|
<el-form-item label="内容分类:">
|
|
|
- <el-select v-model="data.dialogForm.radio" placeholder="请选择内容分类">
|
|
|
+ <el-select v-model="audioData.form.type" placeholder="请选择内容分类">
|
|
|
<el-option v-for="item in data.radioOptions" :key="item.value" :value="item.value" :label="item.label" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="名称:">
|
|
|
- <el-input placeholder="请输入音频名称" />
|
|
|
+ <el-input v-model="audioData.form.name" placeholder="请输入名称" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="分类:">
|
|
|
- <el-select placeholder="请选择音频分类">
|
|
|
- <!-- <el-option /> -->
|
|
|
+ <el-select v-model="audioData.form.sceneId" placeholder="请选择分类">
|
|
|
+ <el-option v-for="item in audioClassData.options" :key="item.id" :value="item.id" :label="item.name" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="当前状态:">
|
|
|
- <el-select placeholder="请选择当前状态">
|
|
|
- <!-- <el-option /> -->
|
|
|
+ <el-select v-model="audioData.form.status" placeholder="请选择当前状态">
|
|
|
+ <el-option v-for="item in sys_change_status" :key="item.value" :value="item.value" :label="item.label" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
- <el-button type="primary" icon="Plus">搜索</el-button>
|
|
|
- <el-button icon="Refresh">重置</el-button>
|
|
|
+ <el-button type="primary" icon="Search" @click="getSearch">搜索</el-button>
|
|
|
+ <el-button icon="Refresh" @click="getRefresh">重置</el-button>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
- <el-table :data="audioData.tableData" v-loading="audioData.loading">
|
|
|
- <el-table-column label="ID" prop="id" align="center"></el-table-column>
|
|
|
- <el-table-column label="名称" prop="name" align="center"></el-table-column>
|
|
|
+ <el-table v-if="audioData.form.type !== 2" ref="table" :data="audioData.tableData" :row-key="rowKey"
|
|
|
+ @selection-change="handleSelectionChange" v-loading="audioData.loading">
|
|
|
+ <el-table-column type="selection" width="55" />
|
|
|
+ <el-table-column label="ID" prop="id" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column label="名称" prop="name" align="center" show-overflow-tooltip />
|
|
|
<el-table-column label="时长" prop="playTime" align="center">
|
|
|
<template #default="scope">
|
|
|
{{ playTime(scope.row.playTime) }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="分类" prop="sceneId" align="center"></el-table-column>
|
|
|
- <el-table-column label="当前状态" prop="status" align="center"></el-table-column>
|
|
|
- <el-table-column label="更新时间" prop="updateTime" align="center"></el-table-column>
|
|
|
- <el-table-column label="操作" align="center">
|
|
|
- <template #default="scope">
|
|
|
- <el-button type="primary" link>选择</el-button>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
+ <el-table-column label="分类" prop="sceneId" align="center" :formatter="sceneFormatter" />
|
|
|
+ <el-table-column label="当前状态" prop="status" align="center" :formatter="statusFormatter" />
|
|
|
+ <el-table-column label="更新时间" prop="updateTime" align="center" show-overflow-tooltip />
|
|
|
</el-table>
|
|
|
+ <div class="audio_table" v-else>
|
|
|
+ <div class="audio" v-for="item in audioData.tableData" :key="item.id" @click="handleChooseAudio(item)">
|
|
|
+ <img src="@/assets/icons/svg/file.svg" width="70" height="70" />
|
|
|
+ <span>{{ item.name }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <pagination v-show="audioData.total > 0" :total="audioData.total" v-model:page="audioData.form.pageNum"
|
|
|
+ v-model:limit="audioData.form.pageSize" @pagination="getAudio" />
|
|
|
+ <template #footer>
|
|
|
+ <el-button type="primary" @click="getPush">确定</el-button>
|
|
|
+ </template>
|
|
|
</el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { useAudioList } from '@/hooks/index'
|
|
|
-const { audioData, getAudio } = useAudioList()
|
|
|
-getAudio()
|
|
|
+import { submit, detail } from '@/api/content/setting'
|
|
|
+import { useAudioList, useAudioClass, useBusinessSelect, useStoreSelect, useDeviceList } from '@/hooks/index'
|
|
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
|
|
|
+const { audioData, getAudio } = useAudioList()
|
|
|
+const { audioClassData, getAudioClass } = useAudioClass()
|
|
|
+getAudioClass()
|
|
|
+const { deviceOptions } = useDeviceList()
|
|
|
+const { storeData, getStore, storeRemote } = useStoreSelect(true)
|
|
|
+const { businessData, getBusiness, businessRemote } = useBusinessSelect(true)
|
|
|
+getBusiness()
|
|
|
+
|
|
|
+const { sys_change_status } = proxy.useDict("sys_change_status")
|
|
|
+
|
|
|
const data = reactive({
|
|
|
+ // 表单
|
|
|
form: {
|
|
|
-
|
|
|
+ audioList: [],
|
|
|
+ listDate: [],
|
|
|
+ tpresetContentInfoReq: [{}]
|
|
|
},
|
|
|
+ // 时间段
|
|
|
dateList: [[]],
|
|
|
- rules: {},
|
|
|
+ // 分页
|
|
|
radioOptions: [{
|
|
|
- value: 1,
|
|
|
+ value: 0,
|
|
|
label: '内容列表'
|
|
|
}, {
|
|
|
- value: 2,
|
|
|
+ value: 1,
|
|
|
label: 'Ohplay音频'
|
|
|
}, {
|
|
|
- value: 3,
|
|
|
+ value: 2,
|
|
|
label: '场景预设'
|
|
|
}],
|
|
|
- dialogForm: {
|
|
|
- radio: 1
|
|
|
- }
|
|
|
+ // 多选
|
|
|
+ selectionList: [],
|
|
|
+ // 校验
|
|
|
+ rules: {
|
|
|
+ audioList: [{
|
|
|
+ required: true, message: '请选择音频', trigger: 'change'
|
|
|
+ }],
|
|
|
+ name: [{
|
|
|
+ required: true, message: '请输入内容名称', trigger: 'blur'
|
|
|
+ }],
|
|
|
+ listDate: [{
|
|
|
+ required: true, message: '请选择播放时间', trigger: 'change'
|
|
|
+ }]
|
|
|
+ },
|
|
|
})
|
|
|
|
|
|
// 弹窗
|
|
@@ -143,13 +184,47 @@ const dialogVisible = ref(false)
|
|
|
// 打开弹窗
|
|
|
function getDialog() {
|
|
|
dialogVisible.value = true
|
|
|
+ getAudio()
|
|
|
+ // 监听
|
|
|
+ watch(() => audioData.tableData, (val) => {
|
|
|
+ if (audioData.form.type !== 2) {
|
|
|
+ nextTick(() => {
|
|
|
+ proxy.$refs.table.clearSelection()
|
|
|
+ if (val && data.form.audioList.length > 0) {
|
|
|
+ data.form.audioList.map(i => {
|
|
|
+ let row = val.find(j => j.id === i.id)
|
|
|
+ if (row) {
|
|
|
+ proxy.$refs.table.toggleRowSelection(row)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 详情
|
|
|
+const getDetail = () => {
|
|
|
+ let e = proxy.$route.query
|
|
|
+ if (e.id) {
|
|
|
+ detail({ id: e.id, storeId: e.storeId }).then(res => {
|
|
|
+ if (res.code === 0) {
|
|
|
+ data.form = res.data
|
|
|
+ data.dateList = []
|
|
|
+ res.data.listDate.map(i => {
|
|
|
+ data.dateList.push([i.startTime, i.endTime])
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
+getDetail()
|
|
|
|
|
|
// 增加时间
|
|
|
function handlePushDate() {
|
|
|
- const boolean = ref(false)
|
|
|
- data.dateList.map(i => boolean.value = i.length === 0 ? true : false)
|
|
|
- if (boolean.value) {
|
|
|
+ let boolean = false
|
|
|
+ data.dateList.map(i => boolean = i.length === 0 ? true : false)
|
|
|
+ if (boolean) {
|
|
|
proxy.$modal.msgError('有时间段未填')
|
|
|
} else {
|
|
|
data.dateList.push([])
|
|
@@ -161,10 +236,140 @@ function handleDeleteDate(index) {
|
|
|
data.dateList.splice(index, 1)
|
|
|
}
|
|
|
|
|
|
+// 校验时间
|
|
|
+const handleChangeDate = (e, index) => {
|
|
|
+ if (e !== null) {
|
|
|
+ data.listDate = []
|
|
|
+ data.form.listDate = []
|
|
|
+ const start = new Date(e[0]).getTime()
|
|
|
+ const end = new Date(e[1]).getTime()
|
|
|
+
|
|
|
+ for (let i = 0; i < data.dateList.length; i++) {
|
|
|
+ if (i !== index) {
|
|
|
+ let st = new Date(data.dateList[i][0]).getTime()
|
|
|
+ let en = new Date(data.dateList[i][1]).getTime()
|
|
|
+
|
|
|
+ if (start >= st && start <= en || end >= st && end <= en || start <= st && end >= en || end <= st && start >= en) {
|
|
|
+ data.dateList.splice(index, 1)
|
|
|
+ proxy.$modal.msgError("该时间段已设置!")
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ data.form.listDate.push({
|
|
|
+ startTime: data.dateList[i][0],
|
|
|
+ endTime: data.dateList[i][1]
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增关联
|
|
|
+const getAdd = () => {
|
|
|
+ data.form.tpresetContentInfoReq.push({})
|
|
|
+}
|
|
|
+
|
|
|
+const handleChange = (e) => {
|
|
|
+ storeData.form.tenantId = e
|
|
|
+ getStore()
|
|
|
+}
|
|
|
+
|
|
|
// 取消
|
|
|
const getClose = () => {
|
|
|
proxy.$tab.closeOpenPage('/content/setting')
|
|
|
}
|
|
|
+
|
|
|
+const getSubmit = () => {
|
|
|
+ proxy.$refs.form.validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ submit(data.form).then(res => {
|
|
|
+ if (res.code === 0) {
|
|
|
+ proxy.$modal.msgSuccess('提交成功!')
|
|
|
+ getClose()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 搜索
|
|
|
+const getSearch = () => {
|
|
|
+ audioData.form.pageNum = 1
|
|
|
+ getAudio()
|
|
|
+}
|
|
|
+
|
|
|
+// 重置
|
|
|
+const getRefresh = () => {
|
|
|
+ audioData.form = {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ type: 0
|
|
|
+ }
|
|
|
+ getAudio()
|
|
|
+}
|
|
|
+
|
|
|
+// 返回id
|
|
|
+const rowKey = (e) => {
|
|
|
+ return e.id
|
|
|
+}
|
|
|
+
|
|
|
+// 多选
|
|
|
+const handleSelectionChange = (e) => {
|
|
|
+ data.selectionList = []
|
|
|
+ e.map(i => {
|
|
|
+ if (data.selectionList.findIndex(j => j.id === i.id) === -1) {
|
|
|
+ data.selectionList.push({
|
|
|
+ audioId: i.id,
|
|
|
+ audioName: i.name,
|
|
|
+ audioType: i.audioType,
|
|
|
+ categoryId: i.sceneId,
|
|
|
+ type: i.type
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 单选
|
|
|
+const handleChooseAudio = (e) => {
|
|
|
+ data.form.audioList = []
|
|
|
+ data.form.audioList.push({
|
|
|
+ ...e,
|
|
|
+ audioName: e.name
|
|
|
+ })
|
|
|
+ proxy.$modal.msgSuccess('选择成功!')
|
|
|
+ dialogVisible.value = false
|
|
|
+}
|
|
|
+
|
|
|
+// 删除
|
|
|
+const handleClose = (e) => {
|
|
|
+ console.log(e);
|
|
|
+}
|
|
|
+
|
|
|
+// 确定
|
|
|
+const getPush = () => {
|
|
|
+ data.form.audioList = []
|
|
|
+ data.form.audioList = JSON.parse(JSON.stringify(data.selectionList))
|
|
|
+ proxy.$modal.msgSuccess('选择成功!')
|
|
|
+ dialogVisible.value = false
|
|
|
+}
|
|
|
+
|
|
|
+// 字典
|
|
|
+const statusFormatter = (row) => {
|
|
|
+ return proxy.selectDictLabel(sys_change_status.value, row.status)
|
|
|
+}
|
|
|
+
|
|
|
+const sceneFormatter = (row) => {
|
|
|
+ if (row.sceneId) {
|
|
|
+ return audioClassData.options.find(i => i.id === row.sceneId).name
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 监听
|
|
|
+watch(() => audioData.form.type, (val) => {
|
|
|
+ data.selectionList = []
|
|
|
+ getAudio()
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -172,42 +377,64 @@ const getClose = () => {
|
|
|
.el-form-item {
|
|
|
width: 500px;
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-.form-btn {
|
|
|
- margin-left: 100px;
|
|
|
+ .el-table__row {
|
|
|
+ .el-form-item {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.audioList {
|
|
|
+.chooseAudio {
|
|
|
:deep(.el-form-item__content) {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: flex-start;
|
|
|
|
|
|
- .el-tag {
|
|
|
- margin-bottom: 15px;
|
|
|
- }
|
|
|
-
|
|
|
- .audio {
|
|
|
- width: 200px;
|
|
|
- height: 200px;
|
|
|
- border: 1px solid #e9e9eb;
|
|
|
- border-radius: 8px;
|
|
|
- margin-bottom: 15px;
|
|
|
+ .audioList {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- box-shadow: 0 0 6px 0 #e9e9eb;
|
|
|
- line-height: 10px;
|
|
|
+ align-items: flex-start;
|
|
|
|
|
|
- span {
|
|
|
- margin-top: 20px;
|
|
|
+ .el-tag {
|
|
|
+ margin-bottom: 15px;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+.audio_table {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+
|
|
|
+ .audio {
|
|
|
+ margin: 10px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.audio {
|
|
|
+ width: 200px;
|
|
|
+ height: 200px;
|
|
|
+ border: 1px solid #e9e9eb;
|
|
|
+ border-radius: 8px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ box-shadow: 0 0 6px 0 #e9e9eb;
|
|
|
+
|
|
|
+ span {
|
|
|
+ width: 160px;
|
|
|
+ height: 40px;
|
|
|
+ line-height: 40px;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
.date {
|
|
|
display: flex;
|
|
|
align-items: center;
|