DESKTOP-SVI9JE1\muzen hai 1 ano
pai
achega
d0c3e6abaa

+ 3 - 0
package.json

@@ -17,6 +17,9 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "2.3.1",
+    "@fullcalendar/core": "^6.1.11",
+    "@fullcalendar/resource": "^6.1.11",
+    "@fullcalendar/resource-timeline": "^6.1.11",
     "@vueup/vue-quill": "1.2.0",
     "@vueuse/core": "10.6.1",
     "axios": "0.27.2",

+ 1 - 1
src/api/content/scene.js

@@ -36,7 +36,7 @@ export function remove(id) {
 }
 
 // 时间轴
-export function timeList(data) {
+export function sceneTime(data) {
   return request({
     url: `/radio/tPresetContent/list`,
     method: "post",

+ 36 - 0
src/api/content/setting.js

@@ -7,4 +7,40 @@ export function audioList(data) {
     method: 'post',
     data
   })
+}
+
+// 时间列表
+export function settimgTime(data) {
+  return request({
+    url: `/radio/tContentPlay/list`,
+    method: 'post',
+    data
+  })
+}
+
+// 提交
+export function submit(data) {
+  return request({
+    url: `/radio/tContentPlay/saveOrUpdate`,
+    method: 'post',
+    data
+  })
+}
+
+// 删除设定
+export function removeSetting(query) {
+  return request({
+    url: `/radio/tContentPlay/deleteById`,
+    method: 'get',
+    params: query
+  })
+}
+
+// 详情
+export function detail(query){
+  return request({
+    url: `/radio/tContentPlay/queryDetailById`,
+    method: 'get',
+    params: query
+  })
 }

+ 9 - 1
src/assets/styles/index.scss

@@ -211,6 +211,14 @@ aside {
   color: #1890ff;
 }
 
-.el-select{
+/* 级联选择器 */
+.el-select,
+.el-range-editor--medium.el-input__inner,
+.el-date-editor--datetimerange.el-input,
+.el-date-editor--datetimerange.el-input__inner {
   width: 100%;
+}
+
+.form-btn {
+  margin-left: 100px;
 }

+ 99 - 38
src/components/GanttChart/index.vue

@@ -23,15 +23,22 @@
         <span class="solid"></span>
       </div>
       <draggable class="label_box" v-model="item.list" group="componentGroup" :item-key="index.toString()"
-        :move="onMove" @end="onEnd">
+        :move="onMove" :end="onEnd">
         <template #item="{ element, index }">
           <div @mousedown.stop style="width: 100%">
             <el-popover placement="bottom" trigger="click" width="300px" popper-class="popper"
               :popper-style="popperStyle" :hide-after="0">
               <div class="title">
-                <h2>{{ element.takeName }}</h2>
+                <h2>{{ props.type === 'scene' ? element.takeName : element.name }}</h2>
                 <div style="display:flex; justify-content: space-between;">
-                  <span>{{ element.listDate.startTime }} - {{ element.listDate.endTime }}</span>
+                  <span v-if="props.type === 'scene'">
+                    {{ element.listDate.startTime }} - {{ element.listDate.endTime }}</span>
+                  <div v-else>
+                    <div v-if="element.listData">{{ element.listDate.startTime.split(' ')[0] }}</div>
+                    <div v-if="element.listData">
+                      {{ element.listDate.startTime.split(' ')[1] }} - {{ element.listDate.endTime.split(' ')[1] }}
+                    </div>
+                  </div>
                   <div style="display:flex; align-items: center">
                     <el-icon style="margin-right: 10px" @click="getDetail(element)">
                       <Edit />
@@ -43,12 +50,12 @@
                 </div>
               </div>
               <div class="main">
-                <span>当前门店:{{ storeData.options.find(i => i.id === element.storeId).name }}</span>
-                <span>当前设备:{{ element.deviceIds }}</span>
+                <span>当前门店:{{ storeName(element.storeId) }}</span>
+                <span>当前设备:{{ deviceName(element.deviceIds) }}</span>
                 <span>当前状态:{{ proxy.selectDictLabel(sys_change_status, element.status) }}</span>
               </div>
               <template #reference>
-                <span class="label">{{ element.takeName }}</span>
+                <span class="label">{{ props.type === 'scene' ? element.takeName : element.name }}</span>
               </template>
             </el-popover>
           </div>
@@ -59,21 +66,22 @@
 </template>
 
 <script setup>
-import { timeList, removeScene } from '@/api/content/scene'
-import { useBusinessSelect, useStoreSelect } from '@/hooks/index'
+import { settimgTime, removeSetting } from '@/api/content/setting'
+import { sceneTime, removeScene } from '@/api/content/scene'
+import { useBusinessSelect, useStoreSelect, useDeviceList } from '@/hooks/index'
 
 const { storeData, getStore, storeRemote } = useStoreSelect()
 const { businessData, getBusiness, businessRemote } = useBusinessSelect(true)
 getBusiness()
+const { deviceOptions } = useDeviceList()
 
 const { proxy } = getCurrentInstance();
 const { sys_change_status } = proxy.useDict("sys_change_status");
 
 const props = defineProps({
-  path: {
-    type: String,
-    default: null
-  }
+  path: String,
+  type: String,
+  date: Date
 })
 
 const data = reactive({
@@ -109,13 +117,23 @@ const data = reactive({
 // 时间轴表单
 const organizationIds = ref(null)
 const storeId = ref(null)
+const nowDate = ref(new Date(props.date))
 
 // 时间段
 function getTime() {
   for (let i = 0; i <= data.timeList.length - 1; i++) {
     data.timeList[i].timer = []
-    data.timeList[i].timer[0] = proxy.hoursToSeconds(data.timeList[i].time[0])
-    data.timeList[i].timer[1] = proxy.hoursToSeconds(data.timeList[i].time[1])
+    let start = proxy.hoursToSeconds(data.timeList[i].time[0])
+    let end = proxy.hoursToSeconds(data.timeList[i].time[1])
+    if (props.type === 'setting') {
+      let y = nowDate.value.getFullYear()
+      let m = nowDate.value.getMonth()
+      let d = nowDate.value.getDate()
+      start = new Date(y, m, d).getTime() + start * 1000
+      end = new Date(y, m, d).getTime() + end * 1000
+    }
+    data.timeList[i].timer[0] = start
+    data.timeList[i].timer[1] = end
   }
 }
 getTime()
@@ -127,28 +145,51 @@ const popperStyle = ref({
 
 // 时间轴
 function getTimeList() {
-  timeList({ storeId: storeId.value }).then(res => {
-    for (let i = 0; i < res.data.length; i++) {
-      for (let j = 0; j < res.data[i].listDate.length; j++) {
-        let start = proxy.hoursToSeconds(res.data[i].listDate[j].startTime)
-        let end = proxy.hoursToSeconds(res.data[i].listDate[j].endTime)
-        const index1 = data.timeList.findIndex(e => {
-          let st = e.timer[0]
-          let en = e.timer[1]
-          return st <= start && start <= en || st <= end && end <= en
-        })
-        data.timeList[index1].list.push({ ...res.data[i], listDate: res.data[i].listDate[j] })
-        const index2 = data.timeList.findIndex(e => {
-          let st = e.timer[0]
-          let en = e.timer[1]
-          return st >= start && en <= end || st >= end && en <= start
-        })
-        data.timeList[index2].list.push({ ...res.data[i], listDate: res.data[i].listDate[j] })
+  data.timeList.map(i => i.list = [])
+  if (props.type === 'scene') {
+    sceneTime({ storeId: storeId.value }).then(res => {
+      modal(res)
+    })
+  } else {
+    settimgTime({ nowDate: proxy.parseTime(nowDate.value.getTime(), "{y}-{m}-{d}"), storeId: storeId.value }).then(res => {
+      modal(res)
+    })
+  }
+}
+
+const modal = (res) => {
+  res.data.forEach(i => {
+    i.listDate.forEach(j => {
+      let start = null
+      let end = null
+      if (props.type === 'scene') {
+        start = proxy.hoursToSeconds(j.startTime)
+        end = proxy.hoursToSeconds(j.endTime)
+      } else {
+        start = new Date(j.startTime).getTime()
+        end = new Date(j.endTime).getTime()
       }
-    }
+      const list = data.timeList.filter((e, index) => {
+        let st = e.timer[0]
+        let en = e.timer[1]
+        if (index !== 24) {
+          return start >= st && end <= en || start <= st && end >= en
+        }
+      })
+      list.map(e => {
+        e.list = []
+        e.list.push({ ...i, listDate: j })
+      })
+    })
   })
 }
 
+watch(() => props.date, (val) => {
+  nowDate.value = val
+  getTime()
+  getTimeList()
+})
+
 // 拖拽内容
 function onMove(params) {
   if (params.to.childElementCount < 1) {
@@ -175,12 +216,21 @@ function onEnd(params) {
 // 删除
 const getDelete = (row) => {
   proxy.$modal.confirm(`是否删除预设名称为:${row.takeName}的数据?`).then(() => {
-    removeScene({ id: row.id }).then(res => {
-      if (res.code === 0) {
-        proxy.$modal.msgSuccess('删除成功!')
-        getTimeList()
-      }
-    })
+    if (props.type === 'setting') {
+      removeSetting({ id: row.id }).then(res => {
+        if (res.code === 0) {
+          proxy.$modal.msgSuccess('删除成功!')
+          getTimeList()
+        }
+      })
+    } else {
+      removeScene({ id: row.id }).then(res => {
+        if (res.code === 0) {
+          proxy.$modal.msgSuccess('删除成功!')
+          getTimeList()
+        }
+      })
+    }
   }).catch(() => { })
 }
 
@@ -212,6 +262,17 @@ function getDetail(query) {
     query
   })
 }
+
+// 计算
+const deviceName = (val) => {
+  let e = deviceOptions.value.find(i => i.clientTypeId == val)
+  return e ? e.name : val
+}
+
+const storeName = (val) => {
+  let e = storeData.options.find(i => i.id === val)
+  return e ? e.name : val
+}
 </script>
 
 <style lang="scss" scoped>

+ 8 - 0
src/components/TimeLine/index.vue

@@ -0,0 +1,8 @@
+<template>
+  <div id='calendar'></div>
+</template>
+
+<script setup>
+import FullCalendar from '@fullcalendar/vue3'
+
+</script>

+ 14 - 17
src/hooks/index.js

@@ -1,24 +1,21 @@
 import { ref, reactive, onMounted, onUnmounted } from "vue";
 
-// // 内容管理-标签分类
+// 标签分类
 import { list as contentClassList } from "@/api/content/class";
 
-export function useContentClass() {
-  const classOptions = ref([]);
-  function getContentClass() {
+export function useAudioClass() {
+  const audioClassData = reactive({
+    options: [],
+  });
+  function getAudioClass() {
     contentClassList().then((res) => {
       if (res.code === 0) {
-        classOptions.value = res.data;
+        audioClassData.options = res.data;
       }
     });
   }
 
-  // 挂载
-  onMounted(() => getContentClass());
-  // 卸载
-  onUnmounted(() => getContentClass());
-
-  return { classOptions };
+  return { audioClassData, getAudioClass };
 }
 
 // // 企业管理-行业管理
@@ -227,20 +224,20 @@ export function useAudioList() {
     form: {
       pageNum: 1,
       pageSize: 10,
-      type: 0
+      type: 0,
     },
     tableData: [],
     loading: false,
-    total: 0
+    total: 0,
   });
 
   const getAudio = () => {
-    audioData.loading = true
+    audioData.loading = true;
     audioList(audioData.form).then((res) => {
       if (res.code === 0) {
-        audioData.tableData = res.data.records
-        audioData.total = res.data.total
-        audioData.loading = false
+        audioData.tableData = res.data.records;
+        audioData.total = res.data.total;
+        audioData.loading = false;
       }
     });
   };

+ 8 - 16
src/utils/playTime.js

@@ -1,18 +1,10 @@
 export function playTime(seconds) {
-  // const date = new Date(seconds * 1000);
-
-  // const hour = date.getHours();
-  // const minute = date.getMinutes();
-  // const second = date.getSeconds();
-  
-
-  // return `${hour.toString().padStart(2, "0")}:
-  //   ${minute.toString().padStart(2, "0")}:
-  //   ${second.toString().padStart(2, "0")}`;
-  const h = Math.floor(60 / 360)
-  const h_re = 60 % 360
-  console.log(h, h_re);
-  // const m = h >= 1 ? Math.floor(seconds % 360 / 60) : Math.floor(seconds / 60)
-  // const s = m > 1 ? Math.floor(seconds % 360 / 60) : ''
-  // console.log(h, m);
+  const h = Math.floor(seconds / 360); // 时
+  const h_re = Math.floor(seconds % 360);
+  const m = Math.floor(h_re / 60); //分
+  const m_re = Math.floor(h_re % 60);
+  const s = Math.floor(m_re); //秒
+  return `${h.toString().padStart(2, "0")}:
+    ${m.toString().padStart(2, "0")}:
+    ${s.toString().padStart(2, "0")}`;
 }

+ 6 - 5
src/views/content/list/index.vue

@@ -10,7 +10,7 @@
       </el-form-item>
       <el-form-item label="音频分类:">
         <el-select v-model="data.form.sceneId" placeholder="请选择音频分类" clearable>
-          <el-option v-for="item in classOptions" :key="item.id" :value="item.id" :label="item.name" />
+          <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="当前状态:">
@@ -61,7 +61,7 @@
         </el-form-item>
         <el-form-item label="音频分类:" prop="sceneId">
           <el-select v-model="data.dialogForm.sceneId" placeholder="请选择标签分类" clearable>
-            <el-option v-for="item in classOptions" :key="item.id" :value="item.id" :label="item.name" />
+            <el-option v-for="item in audioClassData.options" :key="item.id" :value="item.id" :label="item.name" />
           </el-select>
         </el-form-item>
       </el-form>
@@ -76,11 +76,12 @@
 
 <script setup>
 import { list, detail, submit, change } from '@/api/content/list'
-import { useContentClass } from '@/hooks/index.js'
+import { useAudioClass } from '@/hooks/index.js'
 
 const { proxy } = getCurrentInstance();
 const { sys_change_status } = proxy.useDict("sys_change_status")
-const { classOptions } = useContentClass()
+const { audioClassData, getAudioClass } = useAudioClass()
+getAudioClass()
 const baseUrl = ref(import.meta.env.VITE_APP_BASE_API)
 
 // 遮罩层
@@ -236,7 +237,7 @@ function getDelete(row) {
 
 // 字典
 function sceneFormatter(row) {
-  let e = classOptions._rawValue.find(i => i.id === row.sceneId)
+  let e = audioClassData.options.find(i => i.id === row.sceneId)
   return e ? e.name : row.sceneId
 }
 </script>

+ 4 - 8
src/views/content/scene/detail.vue

@@ -145,9 +145,9 @@ function handleChecked(item) {
 
 // 增加时间
 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([])
@@ -188,7 +188,7 @@ const handleChangeDate = (e, index) => {
 
 // 添加门店
 const getAdd = () => {
-  data.form.tpresetContentInfoReq.push([])
+  data.form.tpresetContentInfoReq.push({})
 }
 
 const handleChange = (e) => {
@@ -232,10 +232,6 @@ const getClose = () => {
   }
 }
 
-.form-btn {
-  margin-left: 100px;
-}
-
 .list {
   :deep(.el-form-item__content) {
     display: flex;

+ 1 - 1
src/views/content/scene/index.vue

@@ -24,7 +24,7 @@
         v-model:page="data.form.pageNum" v-model:limit="data.form.pageSize" @pagination="getList" />
     </div>
     <div class="right">
-      <gantt-chart path="/content/scene/detail" />
+      <gantt-chart path="/content/scene/detail" type="scene" />
     </div>
 
     <!-- 弹窗 -->

+ 312 - 85
src/views/content/setting/detail.vue

@@ -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;

+ 7 - 8
src/views/content/setting/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class='app-container'>
     <div class="left">
-      <el-calendar ref="calendar" @click="getDate">
+      <el-calendar ref="calendar" v-model="nowDate">
         <template #header="{ date }">
           <span>{{ date }}</span>
           <el-button link icon="ArrowLeftBold" @click="selectDate('prev-month')" />
@@ -18,7 +18,7 @@
           <el-tab-pane v-for="item in data.tabOptions" :key="item.value" :name="item.value" :label="item.label"
             v-loading="audioData.loading">
             <el-scrollbar :height="220">
-              <draggable :class="['contentList', activeName !== 2 ? 'noScene' : 'scene']" v-model="audioData.tableData"
+              <draggable class="contentList" :style="[activeName !== 2 ? 'flex-direction: column' : 'flex-wrap: wrap;']" v-model="audioData.tableData"
                 item-key="id" chosen-class="chosenClass" data-id="content"
                 :group="{ name: 'componentGroup', pull: 'clone', put: false }" :sort="false" :move="onMove"
                 @end="onEnd">
@@ -45,15 +45,12 @@
       </div>
     </div>
     <div class="right">
-      <gantt-chart path="/content/setting/detail" />
+      <gantt-chart path="/content/setting/detail" type="setting" :date="nowDate" />
     </div>
   </div>
 </template>
 
 <script setup>
-import { list as contentList } from '@/api/content/list'
-import { list as ohplayList } from '@/api/content/ohplay'
-import { list as sceneList } from '@/api/content/scene'
 import { useAudioList } from '@/hooks/index'
 import GanttChart from '@/components/GanttChart'
 
@@ -66,6 +63,8 @@ getAudio()
 const loading = ref(false)
 // tab页
 const activeName = ref(0)
+// 日历
+const nowDate = ref(new Date())
 // 数据
 const data = reactive({
   // tab数组
@@ -87,6 +86,7 @@ const data = reactive({
 })
 
 
+
 // 日历
 const calendar = ref()
 function selectDate(val) {
@@ -95,8 +95,7 @@ function selectDate(val) {
 }
 
 function getDate(e) {
-  console.log(e._vts);
-  console.log(new Date().getTime());
+  nowDate.value = e
 }
 
 // 切换tab

+ 8 - 7
src/views/store/devices/index.vue

@@ -55,9 +55,9 @@
       <el-table-column label="操作" align="center">
         <template #default="scope">
           <el-button type="primary" link @click="getDialog(scope.row.id)">编辑</el-button>
-          <el-button v-if="scope.row.status === 1" type="primary" link
-            @click="getChange(scope.row.id, '上架')">上架</el-button>
-          <el-button v-else type="primary" link @click="getChange(scope.row.id, '下架')">下架</el-button>
+          <el-button v-if="scope.row.status == 1" type="primary" link
+            @click="getChange(scope.row.id, '上架', 0)">上架</el-button>
+          <el-button v-else type="primary" link @click="getChange(scope.row.id, '下架', 1)">下架</el-button>
           <el-button type="danger" link @click="getDelete(item)">删除</el-button>
         </template>
       </el-table-column>
@@ -74,8 +74,9 @@
               <el-dropdown-menu>
                 <el-dropdown-item @click="getDialog(item.id)">编辑</el-dropdown-item>
                 <el-dropdown-item @click="getDelete(item)">删除</el-dropdown-item>
-                <el-dropdown-item v-if="item.status === 1" @click="getChange(scope.row.id, '上架')">上架</el-dropdown-item>
-                <el-dropdown-item v-else @click="getChange(scope.row.id, '下架')">下架</el-dropdown-item>
+                <el-dropdown-item v-if="item.status == 1"
+                  @click="getChange(scope.row.id, '上架', 0)">上架</el-dropdown-item>
+                <el-dropdown-item v-else @click="getChange(scope.row.id, '下架', 1)">下架</el-dropdown-item>
               </el-dropdown-menu>
             </template>
           </el-dropdown>
@@ -251,8 +252,8 @@ const getSubmit = () => {
 }
 
 // 修改状态
-const getChange = (id, title) => {
-  change({ id: id }).then(res => {
+const getChange = (id, title, status) => {
+  change({ id: id, status: status }).then(res => {
     if (res.code === 0) {
       proxy.$modal.msgSuccess(`${title}成功!`)
       getList()

+ 2 - 2
vite.config.js

@@ -31,9 +31,9 @@ export default defineConfig(({ mode, command }) => {
       proxy: {
         // https://cn.vitejs.dev/config/#server-proxy
         '/dev-api': {
-          // target: 'http://testclient.cloud.airsmartser.com/admin',
+          target: 'http://testclient.cloud.airsmartser.com/admin',
           // target: 'http://192.168.198.255:2130', // 付
-          target: 'http://192.168.0.174:2130', // 陈
+          // target: 'http://192.168.0.174:2130', // 陈
           changeOrigin: true,
           rewrite: (p) => p.replace(/^\/dev-api/, '')
         }