调整最新版应用
This commit is contained in:
		
							
								
								
									
										51
									
								
								src/apps/AppAskForm/AppAskForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/apps/AppAskForm/AppAskForm.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="form">
 | 
			
		||||
    <component
 | 
			
		||||
        :is="component"
 | 
			
		||||
        @change="onChange"
 | 
			
		||||
        :params="params">
 | 
			
		||||
    </component>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Tabbar from './components/Tabbar.vue'
 | 
			
		||||
import AddForm from './components/AddForm.vue'
 | 
			
		||||
import Result from './components/Result.vue'
 | 
			
		||||
import {mapActions} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'AppAskForm',
 | 
			
		||||
  appName: '问卷表单管理',
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      component: 'Tabbar',
 | 
			
		||||
      params: {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  components: {
 | 
			
		||||
    Tabbar,
 | 
			
		||||
    Result,
 | 
			
		||||
    AddForm
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['injectJWeixin']),
 | 
			
		||||
    onChange(e) {
 | 
			
		||||
      this.params = e.params
 | 
			
		||||
      this.component = e.type
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  onShow() {
 | 
			
		||||
    document.title = "问卷表单"
 | 
			
		||||
    this.injectJWeixin(['sendChatMessage', 'selectEnterpriseContact', 'shareAppMessage', 'shareWechatMessage']).then(() => {
 | 
			
		||||
      this.$dict.load(['questionnaireStatus', 'questionnaireType', 'questionnaireFieldType'])
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										82
									
								
								src/apps/AppAskForm/AppForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/apps/AppAskForm/AppForm.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <section class="AppForm">
 | 
			
		||||
    <template v-if="showDetail">
 | 
			
		||||
      <form-detail/>
 | 
			
		||||
    </template>
 | 
			
		||||
    <AiResult v-else :tips="errMsg" :status="errStatus"/>
 | 
			
		||||
  </section>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions, mapState} from "vuex";
 | 
			
		||||
import FormDetail from "./components/formDetail";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "AppForm",
 | 
			
		||||
  appName: "问卷表单",
 | 
			
		||||
  inject: {root: {}},
 | 
			
		||||
  components: {FormDetail},
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      access: false,
 | 
			
		||||
      err: ""
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    ...mapState(['user', 'token']),
 | 
			
		||||
    showDetail() {
 | 
			
		||||
      return !!this.$route.query?.id && this.access
 | 
			
		||||
    },
 | 
			
		||||
    errMsg() {
 | 
			
		||||
      this.access && (this.err = "表单不存在")
 | 
			
		||||
      return this.err || "数据读取中..."
 | 
			
		||||
    },
 | 
			
		||||
    errStatus() {
 | 
			
		||||
      return !!this.err ? "error" : "loading"
 | 
			
		||||
    },
 | 
			
		||||
    isPreview() {
 | 
			
		||||
      return !!this.$route.query?.preview
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['getCode', 'getToken']),
 | 
			
		||||
    checkAccess() {
 | 
			
		||||
      let {corpId, code, suiteId, id} = this.$route.query
 | 
			
		||||
      if (this.isPreview) {
 | 
			
		||||
        this.access = true
 | 
			
		||||
      } else if (!!this.token) {
 | 
			
		||||
        this.$http.post("/app/appquestionnairetemplate/commitCheck", null, {
 | 
			
		||||
          params: {id}
 | 
			
		||||
        }).then(res => {
 | 
			
		||||
          if (res?.code == 0) {
 | 
			
		||||
            this.access = true
 | 
			
		||||
          } else {
 | 
			
		||||
            this.err = "无法获取表单"
 | 
			
		||||
          }
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
          this.err = err
 | 
			
		||||
        })
 | 
			
		||||
      } else if (code) {
 | 
			
		||||
        this.getToken({code, corpId, suiteId, isAppForm: true}).then(() => {
 | 
			
		||||
          let {query, path, hash} = this.$route
 | 
			
		||||
          delete query.code
 | 
			
		||||
          this.root.goto({query, path, hash})
 | 
			
		||||
        })
 | 
			
		||||
      } else this.getCode()
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.checkAccess()
 | 
			
		||||
    document.title = "问卷调查"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.AppForm {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										775
									
								
								src/apps/AppAskForm/components/AddForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										775
									
								
								src/apps/AppAskForm/components/AddForm.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,775 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="add-form" v-if="pageShow">
 | 
			
		||||
    <div v-show="!isShowConfig">
 | 
			
		||||
      <div class="header-pic">
 | 
			
		||||
        <image v-if="form.headPicture" :src="form.headPicture"/>
 | 
			
		||||
        <span @click="upload">更换图片</span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="form-info">
 | 
			
		||||
        <h2>文本选项</h2>
 | 
			
		||||
        <div class="form-info__wrapper">
 | 
			
		||||
          <textarea class="title" placeholder="请输入标题 (必填)" :maxlength="30" :auto-height="true"
 | 
			
		||||
                    v-model="form.title"></textarea>
 | 
			
		||||
          <textarea
 | 
			
		||||
              class="content"
 | 
			
		||||
              border="none"
 | 
			
		||||
              :clearable="false"
 | 
			
		||||
              type="textarea"
 | 
			
		||||
              v-model="form.tableExplain"
 | 
			
		||||
              placeholder="请输入表单描述 (选填)"
 | 
			
		||||
              :maxlength="255">
 | 
			
		||||
          </textarea>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <draggable
 | 
			
		||||
          class="components-list"
 | 
			
		||||
          v-model="targetList"
 | 
			
		||||
          :animation="340"
 | 
			
		||||
          scroll
 | 
			
		||||
          element="div"
 | 
			
		||||
          :options="{
 | 
			
		||||
          animation: 340,
 | 
			
		||||
          handle: '.components-item__title'
 | 
			
		||||
        }"
 | 
			
		||||
          draggable=".components-item"
 | 
			
		||||
          :sort="true">
 | 
			
		||||
        <div class="components-item" v-for="(item, index) in targetList" :key="index"
 | 
			
		||||
             @click="toFiledSetting(item, index)">
 | 
			
		||||
          <div class="components-item__title">
 | 
			
		||||
            <div class="components-item__title--left">
 | 
			
		||||
              <em :style="{opacity: item.required ? 1 : 0}">*</em>
 | 
			
		||||
              <i>{{ index + 1 }}.</i>
 | 
			
		||||
              <h2>{{ item.label }}</h2>
 | 
			
		||||
            </div>
 | 
			
		||||
            <image :src="`${$cdn}askform/sc1.png`" @click.stop="removeComponent(index)"
 | 
			
		||||
                   @touchstart.stop="removeComponent(index)"/>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="components-item__filed">
 | 
			
		||||
            <template v-if="(item.type === 'radio')">
 | 
			
		||||
              <u-radio-group v-model="item.value" wrap>
 | 
			
		||||
                <u-radio class="u-radio" disabled style="display: block;" v-for="(field, i) in item.options" :key="i">
 | 
			
		||||
                  <image :src="field.img[0].url" v-if="field.img.length"/>
 | 
			
		||||
                  <span>{{ field.label }}</span>
 | 
			
		||||
                </u-radio>
 | 
			
		||||
              </u-radio-group>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-if="(item.type === 'checkbox')">
 | 
			
		||||
              <u-checkbox-group v-model="item.value" wrap>
 | 
			
		||||
                <u-checkbox class="u-checkbox" disabled :name="field.label" v-for="(field, i) in item.options" :key="i">
 | 
			
		||||
                  <image :src="field.img[0].url" v-if="field.img.length"/>
 | 
			
		||||
                  <span>{{ field.label }}</span>
 | 
			
		||||
                </u-checkbox>
 | 
			
		||||
              </u-checkbox-group>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-if="(item.type === 'select')">
 | 
			
		||||
              <div class="components-item__select">
 | 
			
		||||
                <span>{{ item.placeholder }}</span>
 | 
			
		||||
                <u-icon name="arrow-down" color="#DEDFDF"/>
 | 
			
		||||
              </div>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-if="(item.type === 'upload')">
 | 
			
		||||
              <div class="components-item__select components-item__textarea components-item__upload">
 | 
			
		||||
                <image :src="`${$cdn}askform/upload.png`"/>
 | 
			
		||||
                <span>选择图片(10M以内)</span>
 | 
			
		||||
              </div>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-if="(item.type === 'input')">
 | 
			
		||||
              <div class="components-item__select">
 | 
			
		||||
                <span>{{ item.placeholder }}</span>
 | 
			
		||||
              </div>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-if="(item.type === 'textarea')">
 | 
			
		||||
              <div class="components-item__select components-item__textarea">
 | 
			
		||||
                <span>{{ item.placeholder }}</span>
 | 
			
		||||
              </div>
 | 
			
		||||
            </template>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </draggable>
 | 
			
		||||
      <div class="add-form__btn" @click="isShow = true">
 | 
			
		||||
        <image :src="`${$cdn}askform/add.png`"/>
 | 
			
		||||
        <span>添加问题</span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="add-form__footer">
 | 
			
		||||
        <div class="add-form__footer--item-wrapper">
 | 
			
		||||
          <div class="add-form__footer--item" @click="toPreview">
 | 
			
		||||
            <image :src="`${$cdn}sass/preview.png`"/>
 | 
			
		||||
            <span>预览</span>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="add-form__footer--item" @click="toSetting">
 | 
			
		||||
            <image :src="`${$cdn}sass/setting.png`"/>
 | 
			
		||||
            <span>设置</span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div @click="onConfirm">立即发布</div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <u-popup v-model="isShow" :closeable="false" mode="bottom" @close="isShow = false">
 | 
			
		||||
        <div class="add-popup">
 | 
			
		||||
          <div class="add-popup__title">
 | 
			
		||||
            <h2>添加问题</h2>
 | 
			
		||||
            <image :src="`${$cdn}askform/zk.png`" mode="aspectFit" @click="isShow = false"/>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="add-popup__list">
 | 
			
		||||
            <span @click="toFiledSetting('radio')">单选题</span>
 | 
			
		||||
            <span @click="toFiledSetting('checkbox')">多选题</span>
 | 
			
		||||
            <span @click="toFiledSetting('select')">单下拉框</span>
 | 
			
		||||
            <span @click="toFiledSetting('input')">单行填空</span>
 | 
			
		||||
            <span @click="toFiledSetting('textarea')">多行填空</span>
 | 
			
		||||
            <span @click="toFiledSetting('upload')">上传图片</span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </u-popup>
 | 
			
		||||
      <AiBack custom @back="back"/>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="detail" v-if="isShowConfig">
 | 
			
		||||
      <component
 | 
			
		||||
          :is="component"
 | 
			
		||||
          :index="filedIndex"
 | 
			
		||||
          :filed="filed"
 | 
			
		||||
          @change="onChange"
 | 
			
		||||
          :targetListData="targetList"
 | 
			
		||||
          :formData="form"
 | 
			
		||||
          :filedType="filedType"
 | 
			
		||||
          @back="isShowConfig = false"
 | 
			
		||||
          :id="id"
 | 
			
		||||
          :formConfig="formConfig">
 | 
			
		||||
      </component>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import draggable from 'vuedraggable'
 | 
			
		||||
import FiledConfig from './FiledConfig'
 | 
			
		||||
import FormSetting from './FormSetting'
 | 
			
		||||
import PreviewForm from './PreviewForm'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  props: ['params'],
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      pageShow: false,
 | 
			
		||||
      isShowConfig: false,
 | 
			
		||||
      form: {
 | 
			
		||||
        tableExplain: '详细描述',
 | 
			
		||||
        title: '问卷调查',
 | 
			
		||||
        isShowheadPicture: true,
 | 
			
		||||
        isShowTableExplain: true,
 | 
			
		||||
        isShowBtn: true,
 | 
			
		||||
        headPicture: '',
 | 
			
		||||
        commitType: '1',
 | 
			
		||||
        periodValidityType: '0',
 | 
			
		||||
        actionNotice: '1',
 | 
			
		||||
        dynamicNotice: '1',
 | 
			
		||||
        periodValidityEndTime: '',
 | 
			
		||||
        shareStatus: '0',
 | 
			
		||||
        count: 0,
 | 
			
		||||
        wechatId: '0',
 | 
			
		||||
        type: 0,
 | 
			
		||||
        buttonExplain: '提交',
 | 
			
		||||
        tips: true
 | 
			
		||||
      },
 | 
			
		||||
      templateType: 0,
 | 
			
		||||
      targetList: [],
 | 
			
		||||
      isShow: false,
 | 
			
		||||
      type: 0,
 | 
			
		||||
      id: '',
 | 
			
		||||
      filedType: '',
 | 
			
		||||
      filed: {},
 | 
			
		||||
      filedIndex: '',
 | 
			
		||||
      isQuote: false,
 | 
			
		||||
      touchStart: 0,
 | 
			
		||||
      component: '',
 | 
			
		||||
      formConfig: {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  components: {
 | 
			
		||||
    draggable,
 | 
			
		||||
    PreviewForm,
 | 
			
		||||
    FormSetting,
 | 
			
		||||
    FiledConfig
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.type = Number(this.params.type)
 | 
			
		||||
 | 
			
		||||
    if (this.params.isQuote) {
 | 
			
		||||
      this.isQuote = true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.params.id) {
 | 
			
		||||
      this.id = this.params.id
 | 
			
		||||
      this.getInfo(this.params.id)
 | 
			
		||||
    } else {
 | 
			
		||||
      this.pageShow = true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.init()
 | 
			
		||||
 | 
			
		||||
    uni.$on('setting', res => {
 | 
			
		||||
      this.form = {
 | 
			
		||||
        ...this.form,
 | 
			
		||||
        ...res
 | 
			
		||||
      }
 | 
			
		||||
      this.formConfig = res
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    uni.$on('filedConfig', res => {
 | 
			
		||||
      if (res.index === '-1') {
 | 
			
		||||
        this.targetList.push(res.config)
 | 
			
		||||
      } else {
 | 
			
		||||
        this.$set(this.targetList, [res.index], res.config)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    toSetting() {
 | 
			
		||||
      this.component = 'FormSetting'
 | 
			
		||||
      this.isShowConfig = true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    back() {
 | 
			
		||||
      this.$emit('change', {
 | 
			
		||||
        type: 'Tabbar'
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onChange(e) {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeComponent(index) {
 | 
			
		||||
      this.targetList.splice(index, 1)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    toPreview() {
 | 
			
		||||
      this.component = 'PreviewForm'
 | 
			
		||||
      this.isShowConfig = true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    upload() {
 | 
			
		||||
      let params = {
 | 
			
		||||
        count: 1,
 | 
			
		||||
        sizeType: ['compressed'],
 | 
			
		||||
        sourceType: ['album', 'camera'],
 | 
			
		||||
        success: (res) => {
 | 
			
		||||
          let count = this.fileList?.length + (res.tempFiles?.length || res.tempFile ? 1 : 0)
 | 
			
		||||
          if (count > 1) {
 | 
			
		||||
            return this.$u.toast(`不能超过1个`)
 | 
			
		||||
          }
 | 
			
		||||
          if (res.tempFiles) {
 | 
			
		||||
            res.tempFiles.map((item) => {
 | 
			
		||||
              this.uploadFile(item)
 | 
			
		||||
            })
 | 
			
		||||
          } else if (res?.tempFile) {
 | 
			
		||||
            this.uploadFile(res.tempFile)
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      uni.chooseImage(params)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    uploadFile(img) {
 | 
			
		||||
      uni.showLoading({title: '上传中'})
 | 
			
		||||
      let formData = new FormData()
 | 
			
		||||
      formData.append('file', img)
 | 
			
		||||
      this.$http.post('/admin/file/add2', formData).then((res) => {
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          this.$u.toast('上传成功!')
 | 
			
		||||
          this.form.headPicture = res.data.url
 | 
			
		||||
        }
 | 
			
		||||
      }).catch(res => {
 | 
			
		||||
        this.$u.toast(res)
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onConfirm() {
 | 
			
		||||
      for (let item of this.targetList) {
 | 
			
		||||
        if (item.isShowPoints) {
 | 
			
		||||
          if (item.pointType === '0') {
 | 
			
		||||
            if (!item.answer || JSON.stringify(item.answer) === '[]') {
 | 
			
		||||
              return this.$u.toast(`请输入${item.label}正确答案`)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!item.points) {
 | 
			
		||||
              return this.$u.toast(`请输入${item.label}的分值`)
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (item.pointType === '1') {
 | 
			
		||||
            for (let option of item.options) {
 | 
			
		||||
              if (!option.point) {
 | 
			
		||||
                return this.$u.toast(`请输入${item.label}${option.label}的分值`)
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (item.pointType === '2') {
 | 
			
		||||
            for (let option of item.options) {
 | 
			
		||||
              if (!option.point) {
 | 
			
		||||
                return this.$u.toast(`请输入${item.label}${option.label}的分值`)
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!item.points) {
 | 
			
		||||
              return this.$u.toast(`请输入${item.label}全部答对分值`)
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const fields = this.targetList.map(item => {
 | 
			
		||||
        return {
 | 
			
		||||
          fieldType: item.type,
 | 
			
		||||
          fieldName: item.label,
 | 
			
		||||
          fieldInfo: JSON.stringify(item)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/addOrUpdate`, {
 | 
			
		||||
        ...this.form,
 | 
			
		||||
        fields,
 | 
			
		||||
        status: 1,
 | 
			
		||||
        id: this.isQuote ? '' : this.id,
 | 
			
		||||
        headPicture: this.form.headPicture,
 | 
			
		||||
        type: this.type,
 | 
			
		||||
        templateType: 0
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            this.$emit('change', {
 | 
			
		||||
              type: 'Result',
 | 
			
		||||
              params: {
 | 
			
		||||
                linkUrl: res.data.linkUrl,
 | 
			
		||||
                title: this.form.title,
 | 
			
		||||
                tableExplain: this.form.tableExplain,
 | 
			
		||||
                headPicture: this.form.headPicture
 | 
			
		||||
              }
 | 
			
		||||
            })
 | 
			
		||||
          }, 600)
 | 
			
		||||
        }
 | 
			
		||||
      }).catch(e => {
 | 
			
		||||
        this.$u.toast(e)
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getInfo(id) {
 | 
			
		||||
      uni.showLoading()
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/queryDetailById?id=${id}`).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.form = {
 | 
			
		||||
            ...res.data,
 | 
			
		||||
            headPicture: res.data.headPicture
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          this.type = res.data.type
 | 
			
		||||
 | 
			
		||||
          this.targetList = res.data.fields.map(item => {
 | 
			
		||||
            return JSON.parse(item.fieldInfo)
 | 
			
		||||
          })
 | 
			
		||||
 | 
			
		||||
          this.pageShow = true
 | 
			
		||||
        } else {
 | 
			
		||||
          this.$u.toast(res.msg)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
      }).catch(() => {
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    toFiledSetting(type, index) {
 | 
			
		||||
      this.isShow = false
 | 
			
		||||
      if (index > -1) {
 | 
			
		||||
        this.filed = type
 | 
			
		||||
        this.filedIndex = index
 | 
			
		||||
        this.component = 'FiledConfig'
 | 
			
		||||
        this.isShowConfig = true
 | 
			
		||||
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.filedIndex = ''
 | 
			
		||||
      this.filedType = type
 | 
			
		||||
      this.component = 'FiledConfig'
 | 
			
		||||
      this.isShowConfig = true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    init() {
 | 
			
		||||
      if (this.type == 0) {
 | 
			
		||||
        this.form.headPicture = 'https://cdn.cunwuyun.cn/dvcp/h5/form/interview.png'
 | 
			
		||||
      }
 | 
			
		||||
      if (this.type == 1) {
 | 
			
		||||
        this.form.title = '考试测评'
 | 
			
		||||
        this.form.headPicture = 'https://cdn.cunwuyun.cn/dvcp/h5/form/exam.png'
 | 
			
		||||
      }
 | 
			
		||||
      if (this.type == 2) {
 | 
			
		||||
        this.form.title = '报名登记'
 | 
			
		||||
        this.form.headPicture = 'https://cdn.cunwuyun.cn/dvcp/h5/form/apply.png'
 | 
			
		||||
      }
 | 
			
		||||
      if (this.type == 3) {
 | 
			
		||||
        this.form.title = '满意调查'
 | 
			
		||||
        this.form.headPicture = 'https://cdn.cunwuyun.cn/dvcp/h5/form/satisfaction.png'
 | 
			
		||||
      }
 | 
			
		||||
      if (this.type == 4) {
 | 
			
		||||
        this.form.title = '投票评选'
 | 
			
		||||
        this.form.headPicture = 'https://cdn.cunwuyun.cn/dvcp/h5/form/vote.png'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.add-form {
 | 
			
		||||
  min-height: 100vh;
 | 
			
		||||
  padding-bottom: 140px;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  background: #F3F6F9;
 | 
			
		||||
 | 
			
		||||
  * {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .components-list {
 | 
			
		||||
    padding: 0 20px;
 | 
			
		||||
 | 
			
		||||
    .components-item {
 | 
			
		||||
      margin-top: 24px;
 | 
			
		||||
      padding: 32px;
 | 
			
		||||
      box-shadow: 0 4px 8px 4px rgba(233, 233, 233, 0.39);
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
      overflow: hidden;
 | 
			
		||||
      border: 1px solid #EEEFF0;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      .u-checkbox, .u-radio {
 | 
			
		||||
        display: block;
 | 
			
		||||
 | 
			
		||||
        image {
 | 
			
		||||
          width: 100px;
 | 
			
		||||
          height: 100px;
 | 
			
		||||
          margin: 0 10px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      ::v-deep .u-radio, ::v-deep .u-checkbox {
 | 
			
		||||
        position: relative;
 | 
			
		||||
        margin-bottom: 20px;
 | 
			
		||||
 | 
			
		||||
        &:last-child {
 | 
			
		||||
          margin-bottom: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .u-checkbox__icon-wrap, .u-radio__icon-wrap {
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          top: 4px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .u-radio__label, .u-checkbox__label {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
          margin-right: 0;
 | 
			
		||||
          margin-left: 40px;
 | 
			
		||||
          text-align: justify;
 | 
			
		||||
 | 
			
		||||
          span {
 | 
			
		||||
            line-height: 1.5;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        color: #666;
 | 
			
		||||
        font-size: 26px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .components-item__select {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: space-between;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 80px;
 | 
			
		||||
        margin-bottom: 8px;
 | 
			
		||||
        padding: 0 26px;
 | 
			
		||||
        border: 1px solid #DEDFDF;
 | 
			
		||||
 | 
			
		||||
        &.components-item__textarea {
 | 
			
		||||
          align-items: flex-start;
 | 
			
		||||
          height: 160px;
 | 
			
		||||
          padding-top: 20px;
 | 
			
		||||
 | 
			
		||||
          image {
 | 
			
		||||
            width: 46px;
 | 
			
		||||
            height: 34px;
 | 
			
		||||
            margin-right: 16px;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          span {
 | 
			
		||||
            color: #666;
 | 
			
		||||
            font-size: 26px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &.components-item__upload {
 | 
			
		||||
          justify-content: center;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .components-item__title {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: space-between;
 | 
			
		||||
        margin-bottom: 32px;
 | 
			
		||||
 | 
			
		||||
        em {
 | 
			
		||||
          margin-right: 4px;
 | 
			
		||||
          font-style: normal;
 | 
			
		||||
          color: rgb(226, 33, 32);;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        image {
 | 
			
		||||
          position: relative;
 | 
			
		||||
          flex-shrink: 1;
 | 
			
		||||
          right: -20px;
 | 
			
		||||
          width: 32px;
 | 
			
		||||
          height: 32px;
 | 
			
		||||
          box-sizing: content-box;
 | 
			
		||||
          padding: 30px 20px 30px 20px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        div {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: baseline;
 | 
			
		||||
          max-width: 550px;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
          font-size: 32px;
 | 
			
		||||
 | 
			
		||||
          i {
 | 
			
		||||
            font-style: normal;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          h2 {
 | 
			
		||||
            font-weight: 600;
 | 
			
		||||
            font-size: 32px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .add-popup {
 | 
			
		||||
    height: 440px;
 | 
			
		||||
    border-radius: 20px 20px 0 0;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
 | 
			
		||||
    .add-popup__title {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      position: relative;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      height: 96px;
 | 
			
		||||
      border-bottom: 1px solid #E4E5E6;
 | 
			
		||||
 | 
			
		||||
      h2 {
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        font-weight: 600;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      image {
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        right: 32px;
 | 
			
		||||
        top: 50%;
 | 
			
		||||
        width: 30px;
 | 
			
		||||
        height: 20px;
 | 
			
		||||
        transform: translateY(-50%);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .add-popup__list {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-wrap: wrap;
 | 
			
		||||
      padding: 0 34px;
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        width: calc((100% - 64px) / 3);
 | 
			
		||||
        height: 78px;
 | 
			
		||||
        line-height: 78px;
 | 
			
		||||
        margin-top: 32px;
 | 
			
		||||
        margin-right: 32px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        border-radius: 8px;
 | 
			
		||||
        border: 1px solid #E4E5E6;
 | 
			
		||||
 | 
			
		||||
        &:nth-of-type(3n) {
 | 
			
		||||
          margin-right: 0;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .add-form__footer {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    z-index: 1;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
 | 
			
		||||
    & > div {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        color: #fff;
 | 
			
		||||
        font-size: 36px;
 | 
			
		||||
        background: #3192F4;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          opacity: 0.8;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .add-form__footer--item-wrapper {
 | 
			
		||||
    .add-form__footer--item {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      flex: 1;
 | 
			
		||||
 | 
			
		||||
      image {
 | 
			
		||||
        display: block;
 | 
			
		||||
        width: 48px;
 | 
			
		||||
        height: 48px;
 | 
			
		||||
        margin: 0 auto;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        display: block;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        color: #999;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          background: #eee;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .add-form__btn {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    width: 214px;
 | 
			
		||||
    height: 66px;
 | 
			
		||||
    line-height: 66px;
 | 
			
		||||
    margin: 64px auto 0;
 | 
			
		||||
    background: #FFFFFF;
 | 
			
		||||
    border-radius: 34px;
 | 
			
		||||
 | 
			
		||||
    &:active {
 | 
			
		||||
      opacity: 0.8;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    image {
 | 
			
		||||
      width: 28px;
 | 
			
		||||
      height: 28px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    span {
 | 
			
		||||
      margin-left: 16px;
 | 
			
		||||
      color: #4392E6;
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  * {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .form-info {
 | 
			
		||||
    padding: 0 20px;
 | 
			
		||||
 | 
			
		||||
    & > h2 {
 | 
			
		||||
      height: 76px;
 | 
			
		||||
      line-height: 76px;
 | 
			
		||||
      color: #999999;
 | 
			
		||||
      font-weight: normal;
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .form-info__wrapper {
 | 
			
		||||
      padding: 0 18px;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      .title {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        padding: 22px 0;
 | 
			
		||||
        font-size: 36px;
 | 
			
		||||
        border-bottom: 1px solid #F1F2F3;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .content {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        padding: 30px 0 !important;
 | 
			
		||||
        color: #333;
 | 
			
		||||
        font-size: 28px !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .header-pic {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    font-size: 0;
 | 
			
		||||
 | 
			
		||||
    span {
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      bottom: 16px;
 | 
			
		||||
      right: 16px;
 | 
			
		||||
      z-index: 1;
 | 
			
		||||
      width: 148px;
 | 
			
		||||
      height: 56px;
 | 
			
		||||
      line-height: 56px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      color: #fff;
 | 
			
		||||
      font-size: 26px;
 | 
			
		||||
      background: rgba(0, 0, 0, 0.16);
 | 
			
		||||
      border-radius: 28px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    image {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      height: 320px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .u-radio, ::v-deep .u-checkbox {
 | 
			
		||||
    align-items: baseline;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										194
									
								
								src/apps/AppAskForm/components/AddList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								src/apps/AppAskForm/components/AddList.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="template-wrapper">
 | 
			
		||||
    <div class="form-list">
 | 
			
		||||
      <div
 | 
			
		||||
          class="form-list__item"
 | 
			
		||||
          @click="toAdd(index)"
 | 
			
		||||
          :style="{'background-image': `url(${$cdn}askform/${index + 1}.png)`}"
 | 
			
		||||
          v-for="(item, index) in itemList"
 | 
			
		||||
          :key="index">
 | 
			
		||||
        <h2>{{ item.name }}</h2>
 | 
			
		||||
        <div>立即创建</div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="template" v-if="list.length">
 | 
			
		||||
      <h2>共享模板</h2>
 | 
			
		||||
      <div class="template-list">
 | 
			
		||||
        <div class="template-item" v-for="(item, index) in list" :key="index" hover-class="bg-hover"
 | 
			
		||||
             @click="quote(item.id)">
 | 
			
		||||
          <image :src="`${$cdn}askform/6.png`"/>
 | 
			
		||||
          <h2>{{ item.title }}</h2>
 | 
			
		||||
          <u-icon name="arrow-right" color="#E1E2E3"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'addList',
 | 
			
		||||
  label: '新建项目',
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      itemList: [{
 | 
			
		||||
        name: '问卷调查'
 | 
			
		||||
      }, {
 | 
			
		||||
        name: '考试测评'
 | 
			
		||||
      }, {
 | 
			
		||||
        name: '报名登记'
 | 
			
		||||
      }, {
 | 
			
		||||
        name: '满意调查'
 | 
			
		||||
      }, {
 | 
			
		||||
        name: '投票评选'
 | 
			
		||||
      }],
 | 
			
		||||
      list: []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.getList()
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    toAdd(type) {
 | 
			
		||||
      this.$emit('change', {
 | 
			
		||||
        type: 'AddForm',
 | 
			
		||||
        params: {
 | 
			
		||||
          type
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    quote(id) {
 | 
			
		||||
      this.$emit('change', {
 | 
			
		||||
        type: 'AddForm',
 | 
			
		||||
        params: {
 | 
			
		||||
          id,
 | 
			
		||||
          isQuote: 1
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getList() {
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/list`, null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          current: 1,
 | 
			
		||||
          templateType: 1,
 | 
			
		||||
          size: 10000
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.list = res.data.records
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.template-wrapper {
 | 
			
		||||
  padding-bottom: 120px;
 | 
			
		||||
 | 
			
		||||
  .template {
 | 
			
		||||
    margin: 32px 32px 0;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    border-radius: 8px;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
 | 
			
		||||
    & > h2 {
 | 
			
		||||
      height: 88px;
 | 
			
		||||
      line-height: 88px;
 | 
			
		||||
      padding: 0 24px;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      font-size: 30px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .template-item {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      height: 104px;
 | 
			
		||||
      padding: 0 24px;
 | 
			
		||||
      border-bottom: 1px solid #D8DDE6;
 | 
			
		||||
 | 
			
		||||
      &:active {
 | 
			
		||||
        background-color: #eee;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        border: none;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      image {
 | 
			
		||||
        width: 36px;
 | 
			
		||||
        height: 42px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      i {
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        color: #E1E2E3;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      h2 {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        padding: 0 18px;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        font-weight: normal;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
        text-overflow: ellipsis;
 | 
			
		||||
        white-space: nowrap;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .form-list {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-wrap: wrap;
 | 
			
		||||
    padding: 0 32px 0;
 | 
			
		||||
 | 
			
		||||
    div {
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .form-list__item {
 | 
			
		||||
      width: calc(50% - 13px);
 | 
			
		||||
      height: 216px;
 | 
			
		||||
      margin: 32px 24px 0 0;
 | 
			
		||||
      padding: 40px 20px 52px;
 | 
			
		||||
      background-color: #FFFFFF;
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
      background-size: 100% 100%;
 | 
			
		||||
 | 
			
		||||
      &:active {
 | 
			
		||||
        background-color: #eee;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:nth-of-type(2n) {
 | 
			
		||||
        margin-right: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      div {
 | 
			
		||||
        width: 148px;
 | 
			
		||||
        height: 48px;
 | 
			
		||||
        line-height: 48px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        color: #fff;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        background: #6BA1F9;
 | 
			
		||||
        border-radius: 24px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      h2 {
 | 
			
		||||
        margin-bottom: 32px;
 | 
			
		||||
        padding-left: 10px;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-weight: 700;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										547
									
								
								src/apps/AppAskForm/components/FiledConfig.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										547
									
								
								src/apps/AppAskForm/components/FiledConfig.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,547 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="form-config">
 | 
			
		||||
    <div class="config-group">
 | 
			
		||||
      <div class="config-item">
 | 
			
		||||
        <u-input class="form-maintitle" :maxlength="200" v-model="config.label"
 | 
			
		||||
                 :placeholder="`请输入${config.fixedLabel||''}标题 ${config.required ? '(必填)' : ''}`"
 | 
			
		||||
                 placeholder-style="color: #999999; font-weight: 600"/>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item__select--wrapper" v-if="['radio', 'select', 'checkbox'].includes(config.type)">
 | 
			
		||||
        <div class="config-item__select" v-for="(item, index) in config.options" :key="index">
 | 
			
		||||
          <image class="config-icon" :src="`${$cdn}askform/del.png`" @click="removeOptions(index)"/>
 | 
			
		||||
          <div class="config-item__upload" v-if="config.type !== 'select'" @click="upload(index)">
 | 
			
		||||
            <u-icon color="#8c9dc3" name="plus" v-if="!item.img.length"></u-icon>
 | 
			
		||||
            <image v-else :src="item.img[0].url"/>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="textarea">
 | 
			
		||||
            <textarea type="textarea" placeholder-style="color: #CDCDCF" :auto-height="true" v-model="item.label"
 | 
			
		||||
                      :maxlength="100" placeholder="请输入选项"/>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__select config-item__select--add" @click="addOptions">
 | 
			
		||||
          <image class="config-icon" :src="`${$cdn}askform/zj.png`"/>
 | 
			
		||||
          <span>添加选项</span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="config-group">
 | 
			
		||||
      <div class="config-item" v-if="!['radio', 'upload', 'checkbox', 'select'].includes(config.type)">
 | 
			
		||||
        <div class="config-item__left">
 | 
			
		||||
          <span>说明文字</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right">
 | 
			
		||||
          <u-input v-model="config.placeholder" placeholder="请输入说明文字" input-align="right"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item">
 | 
			
		||||
        <div class="config-item__left">
 | 
			
		||||
          <span>是否必填</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right">
 | 
			
		||||
          <u-switch v-model="config.required" active-value="1" inactive-value="0" :size="40"
 | 
			
		||||
                    active-color="#1088F9"></u-switch>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item" v-if="!['upload'].includes(config.type)">
 | 
			
		||||
        <div class="config-item__left">
 | 
			
		||||
          <span>答案与分值</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right">
 | 
			
		||||
          <u-switch v-model="config.isShowPoints" :size="40" active-color="#1088F9"></u-switch>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item" v-if="['input', 'textarea'].includes(config.type) && config.isShowPoints">
 | 
			
		||||
        <div class="config-item__left">
 | 
			
		||||
          <span>正确答案</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right">
 | 
			
		||||
          <u-input v-model="config.answer" placeholder="请输入正确答案" input-align="right"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item"
 | 
			
		||||
           v-if="['radio', 'select'].includes(config.type) && config.isShowPoints && config.pointType === '0'">
 | 
			
		||||
        <div class="config-item__left">
 | 
			
		||||
          <span>正确答案</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right config-item__text" @click="isShowAnswer = true">
 | 
			
		||||
          <span>{{ config.answer ? config.answer : '请选择正确答案' }}</span>
 | 
			
		||||
          <u-icon name="arrow-down-fill" color="#c0c4cc" size="24"></u-icon>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item config-item__checkbox"
 | 
			
		||||
           v-if="config.isShowPoints && ['radio', 'select', 'checkbox'].includes(config.type)">
 | 
			
		||||
        <div class="config-item__left">
 | 
			
		||||
          <span>计分方式</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right" @click="isShowType = true">
 | 
			
		||||
          <span>{{ pointTypeName ? pointTypeName : '请选择' }}</span>
 | 
			
		||||
          <u-icon name="arrow-right" color="#E1E2E3"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item config-item__answer config-item__checkbox"
 | 
			
		||||
           v-if="['checkbox'].includes(config.type) && config.isShowPoints && config.pointType === '0'">
 | 
			
		||||
        <div class="config-item__left">
 | 
			
		||||
          <span>正确答案</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right">
 | 
			
		||||
          <u-checkbox-group wrap @change="onCheckboxChange">
 | 
			
		||||
            <u-checkbox v-model="field.checked" :name="field.label" v-if="field.label"
 | 
			
		||||
                        v-for="(field, i) in config.options" :key="i">
 | 
			
		||||
              <span>{{ field.label }}</span>
 | 
			
		||||
            </u-checkbox>
 | 
			
		||||
          </u-checkbox-group>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item" v-if="config.isShowPoints && config.pointType === '0'">
 | 
			
		||||
        <div class="config-item__left">
 | 
			
		||||
          <span>本题分值</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right">
 | 
			
		||||
          <u-input v-model="config.points" type="number" placeholder="请输入本题分值" input-align="right"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div v-if="config.isShowPoints && config.pointType === '1'">
 | 
			
		||||
        <div class="config-item" v-for="(item, index) in config.options" :key="index">
 | 
			
		||||
          <div class="config-item__left">
 | 
			
		||||
            <span>{{ item.label }}</span>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="config-item__right">
 | 
			
		||||
            <u-input v-model="item.point" placeholder="请输入分值" input-align="right"/>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item config-item__point" v-if="config.isShowPoints && config.pointType === '2'">
 | 
			
		||||
        <u-checkbox-group wrap @change="onCheckboxChange">
 | 
			
		||||
          <u-checkbox v-model="field.checked" :name="field.label" v-if="field.label"
 | 
			
		||||
                      v-for="(field, i) in config.options" :key="i">
 | 
			
		||||
            <span>{{ field.label }}</span>
 | 
			
		||||
            <u-input v-model="field.point" type="number" placeholder="请输入分值" input-align="right"/>
 | 
			
		||||
          </u-checkbox>
 | 
			
		||||
        </u-checkbox-group>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="config-item" v-if="config.isShowPoints && config.pointType === '2'">
 | 
			
		||||
        <div class="config-item__left" style="padding-left: 20px">
 | 
			
		||||
          <span>全部答对</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="config-item__right">
 | 
			
		||||
          <u-input v-model="config.points" type="number" placeholder="请输入全部答对分值" input-align="right"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <u-select :list="config.options" :default-value="defaultAnswer" value-name="value" label-name="label"
 | 
			
		||||
              v-model="isShowAnswer" @confirm="answerChange"></u-select>
 | 
			
		||||
    <u-select :list="config.pointDict" :default-value="defaultType" value-name="dictValue" label-name="dictName"
 | 
			
		||||
              v-model="isShowType" @confirm="pointTypeChange"></u-select>
 | 
			
		||||
    <div class="add-form__footer">
 | 
			
		||||
      <div @click="back">
 | 
			
		||||
        <span>取消</span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div @click="confirm">确定</div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {components} from './config'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  props: ['filed', 'index', 'filedType'],
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      isShowType: false,
 | 
			
		||||
      isShowAnswer: false,
 | 
			
		||||
      config: {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  mounted() {
 | 
			
		||||
    if (this.index !== '') {
 | 
			
		||||
      this.config = this.filed
 | 
			
		||||
      return false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    console.log(components)
 | 
			
		||||
    this.config = JSON.parse(JSON.stringify(components.filter(v => v.type === this.filedType)[0]))
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  computed: {
 | 
			
		||||
    pointTypeName() {
 | 
			
		||||
      if (!this.config.pointDict) return ''
 | 
			
		||||
 | 
			
		||||
      return this.config.pointDict.filter(v => v.dictValue === this.config.pointType)[0].dictName
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    defaultType() {
 | 
			
		||||
      if (!this.config.pointType) return [0]
 | 
			
		||||
 | 
			
		||||
      return [Number(this.config.pointType)]
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    defaultAnswer() {
 | 
			
		||||
      if (!this.config.answer) return [0]
 | 
			
		||||
 | 
			
		||||
      let index = 0
 | 
			
		||||
      if (this.config.answer) {
 | 
			
		||||
        this.config.options?.forEach((v, i) => {
 | 
			
		||||
          if (v.label === this.config.answer) {
 | 
			
		||||
            index = i
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return [index]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    answerChange(e) {
 | 
			
		||||
      this.config.answer = e[0].label
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    pointTypeChange(e) {
 | 
			
		||||
      console.log(e)
 | 
			
		||||
      this.config.pointType = e[0].value
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onCheckboxChange(e) {
 | 
			
		||||
      this.config.answer = e
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    upload(index) {
 | 
			
		||||
      let params = {
 | 
			
		||||
        count: 1,
 | 
			
		||||
        sizeType: ['compressed'],
 | 
			
		||||
        sourceType: ['album', 'camera'],
 | 
			
		||||
        success: (res) => {
 | 
			
		||||
          let count = this.fileList?.length + (res.tempFiles?.length || res.tempFile ? 1 : 0)
 | 
			
		||||
          if (count > 1) {
 | 
			
		||||
            return this.$u.toast(`不能超过1个`)
 | 
			
		||||
          }
 | 
			
		||||
          if (res.tempFiles) {
 | 
			
		||||
            res.tempFiles.map((item) => {
 | 
			
		||||
              this.uploadFile(item, index)
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      uni.chooseImage(params)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    uploadFile(img, index) {
 | 
			
		||||
      uni.showLoading({title: '上传中'})
 | 
			
		||||
      let formData = new FormData()
 | 
			
		||||
      formData.append('file', img)
 | 
			
		||||
      this.$http.post('/admin/file/add2', formData).then((res) => {
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          this.$u.toast('上传成功!')
 | 
			
		||||
          this.$set(this.config.options[index], 'img', [res.data])
 | 
			
		||||
        }
 | 
			
		||||
      }).catch(res => {
 | 
			
		||||
        this.$u.toast(res)
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeOptions(index) {
 | 
			
		||||
      const len = this.config.options.length
 | 
			
		||||
      const label = this.config.options[index].label
 | 
			
		||||
      if (len === 2) {
 | 
			
		||||
        return this.$u.toast('选项不能少于2个')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (this.config.type === 'checkbox') {
 | 
			
		||||
        const answerIndex = this.config.answer.indexOf(label)
 | 
			
		||||
        if (answerIndex > -1) {
 | 
			
		||||
          this.config.answer.splice(answerIndex, 1)
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        if (label === this.config.answer) {
 | 
			
		||||
          this.config.answer = ''
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.config.options.splice(index, 1)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    back() {
 | 
			
		||||
      this.$emit('back')
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    confirm() {
 | 
			
		||||
      uni.$emit('filedConfig', {
 | 
			
		||||
        config: this.config,
 | 
			
		||||
        index: this.index === '' ? '-1' : this.index
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      this.back()
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addOptions() {
 | 
			
		||||
      const len = this.config.options.length
 | 
			
		||||
      let label = `选项${len + 1}`
 | 
			
		||||
 | 
			
		||||
      const index = this.config.options.findIndex(v => label === v.label)
 | 
			
		||||
      if (index > -1) {
 | 
			
		||||
        label = `新选项${len + 1}`
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.config.options.push({
 | 
			
		||||
        label: label,
 | 
			
		||||
        value: '',
 | 
			
		||||
        point: '',
 | 
			
		||||
        img: '',
 | 
			
		||||
        checked: false
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.form-config {
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  padding-bottom: 130px;
 | 
			
		||||
 | 
			
		||||
  .form-maintitle {
 | 
			
		||||
    ::v-deep .uni-input-input {
 | 
			
		||||
      font-size: 36px;
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .config-item__select--wrapper {
 | 
			
		||||
    .config-item__select {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
 | 
			
		||||
      ::v-deep .u-input__input {
 | 
			
		||||
        height: 100%;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .textarea {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        min-height: 104px;
 | 
			
		||||
        padding: 16px 0;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        border-bottom: 1px solid #dfe8f8;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      textarea {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .config-icon {
 | 
			
		||||
        width: 36px;
 | 
			
		||||
        height: 36px;
 | 
			
		||||
        margin-right: 12px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .config-item__select--add {
 | 
			
		||||
      height: 120px;
 | 
			
		||||
 | 
			
		||||
      .config-icon {
 | 
			
		||||
        margin-right: 18px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        color: #1D74F4;
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .config-group {
 | 
			
		||||
    margin-bottom: 32px;
 | 
			
		||||
    padding: 0 32px;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
 | 
			
		||||
    .config-item__upload {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      width: 60px;
 | 
			
		||||
      height: 60px;
 | 
			
		||||
      margin-right: 20px;
 | 
			
		||||
      border: 1px solid rgb(208, 212, 220);
 | 
			
		||||
      background-color: #fbfdff;
 | 
			
		||||
 | 
			
		||||
      image {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .config-item {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: space-between;
 | 
			
		||||
      min-height: 100px;
 | 
			
		||||
      padding: 16px 0;
 | 
			
		||||
      border-bottom: 1px solid #dfe8f8;
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        border: none;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      ::v-deep .u-radio__label, ::v-deep .u-checkbox__label {
 | 
			
		||||
        margin-right: 0;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
 | 
			
		||||
        span {
 | 
			
		||||
          max-width: 400 rpx;
 | 
			
		||||
          line-height: 1.2;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .config-item__left {
 | 
			
		||||
        max-width: 400px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .config-item__right {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        text-align: right;
 | 
			
		||||
        padding-left: 30px;
 | 
			
		||||
 | 
			
		||||
        &.config-item__text {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
          justify-content: flex-end;
 | 
			
		||||
 | 
			
		||||
          span {
 | 
			
		||||
            max-width: 400px;
 | 
			
		||||
            margin-right: 10px;
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
            text-overflow: ellipsis;
 | 
			
		||||
            white-space: nowrap;
 | 
			
		||||
            word-break: keep-all;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .text {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &.config-item__answer {
 | 
			
		||||
        display: block;
 | 
			
		||||
        padding: 20px 0;
 | 
			
		||||
 | 
			
		||||
        .config-item__left {
 | 
			
		||||
          margin-bottom: 32 rpx;
 | 
			
		||||
 | 
			
		||||
          span {
 | 
			
		||||
            word-break: break-all;
 | 
			
		||||
            color: #333;
 | 
			
		||||
            font-size: 30px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .config-item__right {
 | 
			
		||||
          width: 100%;
 | 
			
		||||
          padding-left: 0;
 | 
			
		||||
          text-align: left;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ::v-deep .u-checkbox {
 | 
			
		||||
      align-items: baseline;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .config-item__checkbox {
 | 
			
		||||
      height: auto;
 | 
			
		||||
      padding: 14px 0;
 | 
			
		||||
 | 
			
		||||
      ::v-deep .u-checkbox, ::v-deep .u-radio {
 | 
			
		||||
        // justify-content: flex-end;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .config-item__point {
 | 
			
		||||
      height: auto;
 | 
			
		||||
      padding: 0;
 | 
			
		||||
 | 
			
		||||
      ::v-deep .u-checkbox {
 | 
			
		||||
        justify-content: inherit;
 | 
			
		||||
        min-height: 100px;
 | 
			
		||||
        padding: 14px 0;
 | 
			
		||||
        border-bottom: 1px solid #eee;
 | 
			
		||||
 | 
			
		||||
        &:last-child {
 | 
			
		||||
          border: none;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .u-checkbox__label {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
          justify-content: space-between;
 | 
			
		||||
          flex: 1;
 | 
			
		||||
          margin-right: 0;
 | 
			
		||||
 | 
			
		||||
          .u-input {
 | 
			
		||||
            flex: 1;
 | 
			
		||||
            max-width: 400px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  * {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .add-form__footer {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    z-index: 1;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
 | 
			
		||||
    div {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      &:first-child:active {
 | 
			
		||||
        background: #eee;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        color: #fff;
 | 
			
		||||
        font-size: 36px;
 | 
			
		||||
        background: #3192F4;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          opacity: 0.8;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
        line-height: 112px;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          background: #eee;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										313
									
								
								src/apps/AppAskForm/components/FormSetting.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								src/apps/AppAskForm/components/FormSetting.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,313 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="form-setting">
 | 
			
		||||
    <h2>表单设置</h2>
 | 
			
		||||
    <div class="form-setting__list">
 | 
			
		||||
      <div class="setting-item">
 | 
			
		||||
        <div class="setting-item__left">
 | 
			
		||||
          <span>截止时间</span>
 | 
			
		||||
          <image :src="`${$cdn}askform/bz.png`" @click="tips = '表单截止后,用户打开表单会提示此表单已结束' , isShowModal = true"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="setting-item__right">
 | 
			
		||||
          <u-radio-group v-model="periodValidityType" active-color="#1088F9">
 | 
			
		||||
            <u-radio name="0" label="永久有效" style="padding-right: 20rpx;">永久有效</u-radio>
 | 
			
		||||
            <u-radio name="1" label="自定义时间">自定义时间</u-radio>
 | 
			
		||||
          </u-radio-group>
 | 
			
		||||
          <u-icon name="arrow-right" color="#E1E2E3"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="setting-item" v-if="periodValidityType === '1'" @click="isShowTime = true">
 | 
			
		||||
        <div class="setting-item__left">
 | 
			
		||||
          <span>截至时间</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="setting-item__right">
 | 
			
		||||
          <span>{{ periodValidityEndTime }}</span>
 | 
			
		||||
          <u-icon name="arrow-right" color="#E1E2E3"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="setting-item">
 | 
			
		||||
        <div class="setting-item__left">
 | 
			
		||||
          <span>匹配客户方式</span>
 | 
			
		||||
          <image :src="`${$cdn}askform/bz.png`" @click="tips = '将参与活动的微信客户和企业微信客户匹配' , isShowModal = true"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="setting-item__right">
 | 
			
		||||
          <span>客户微信ID匹配</span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="setting-item">
 | 
			
		||||
        <div class="setting-item__left">
 | 
			
		||||
          <span>提交次数</span>
 | 
			
		||||
          <image :src="`${$cdn}askform/bz.png`" @click="tips = '此功能发布后不可修改' , isShowModal = true"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="setting-item__right">
 | 
			
		||||
          <u-radio-group v-model="commitType" active-color="#1088F9">
 | 
			
		||||
            <u-radio name="0" label="不限次数" style="padding-right: 20rpx;">不限次数</u-radio>
 | 
			
		||||
            <u-radio name="1" label="限提交一次">限提交一次</u-radio>
 | 
			
		||||
          </u-radio-group>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <!-- <div class="setting-item">
 | 
			
		||||
        <div class="setting-item__left">
 | 
			
		||||
          <span>行为通知</span>
 | 
			
		||||
          <image :src="`${$cdn}askform/bz.png`" @click="tips = '当客户点击或者发布表单时,发送表单的员工将会受到消息提醒' , isShowModal = true" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="setting-item__right">
 | 
			
		||||
          <u-switch v-model="actionNotice" active-value="1" :size="40" active-color="#1088F9"></u-switch>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="setting-item">
 | 
			
		||||
        <div class="setting-item__left">
 | 
			
		||||
          <span>动态通知</span>
 | 
			
		||||
          <image :src="`${$cdn}askform/bz.png`" @click="tips = '当客户点击或者发布表单时,会将客户的打开行为记录在客户动态里' , isShowModal = true" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="setting-item__right">
 | 
			
		||||
          <u-switch v-model="dynamicNotice" active-value="1" :size="40" active-color="#1088F9"></u-switch>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div> -->
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="add-form__footer">
 | 
			
		||||
      <div @click="back">
 | 
			
		||||
        <span>取消</span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div @click="confirm">{{ type === 'edit' ? '发布' : '确定' }}</div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <u-modal v-model="isShowModal" :content="tips"></u-modal>
 | 
			
		||||
    <u-picker mode="time" v-model="isShowTime" :show-time-tag="true" @close="isShowTime = false" @confirm="onTimeChange"
 | 
			
		||||
              :params="params"></u-picker>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  props: ['id', 'formConfig', 'type'],
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      params: {
 | 
			
		||||
        year: true,
 | 
			
		||||
        month: true,
 | 
			
		||||
        day: true,
 | 
			
		||||
        hour: true,
 | 
			
		||||
        minute: true,
 | 
			
		||||
        second: true
 | 
			
		||||
      },
 | 
			
		||||
      tips: '',
 | 
			
		||||
      isShowModal: false,
 | 
			
		||||
      actionNotice: true,
 | 
			
		||||
      dynamicNotice: true,
 | 
			
		||||
      commitType: '1',
 | 
			
		||||
      wechatId: '0',
 | 
			
		||||
      periodValidityEndTime: '',
 | 
			
		||||
      isShowTime: false,
 | 
			
		||||
      periodValidityType: '0'
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  mounted() {
 | 
			
		||||
    if (this.id) {
 | 
			
		||||
      this.id = this.id
 | 
			
		||||
      this.getInfo(this.id)
 | 
			
		||||
      this.type = this.type
 | 
			
		||||
    } else if (this.formConfig) {
 | 
			
		||||
      const res = this.formConfig
 | 
			
		||||
      this.periodValidityType = res.periodValidityType || '0'
 | 
			
		||||
      this.commitType = res.commitType || '1'
 | 
			
		||||
      this.actionNotice = res.actionNotice === '1'
 | 
			
		||||
      this.dynamicNotice = res.dynamicNotice === '1'
 | 
			
		||||
 | 
			
		||||
      if (res.periodValidityType === '1') {
 | 
			
		||||
        this.periodValidityEndTime = res.periodValidityEndTime
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    onTimeChange(e) {
 | 
			
		||||
      this.periodValidityEndTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}:${e.second}`
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    back() {
 | 
			
		||||
      this.$emit('back')
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getInfo(id) {
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/queryDetailById?id=${id}`).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.periodValidityType = res.data.periodValidityType
 | 
			
		||||
          this.commitType = res.data.commitType
 | 
			
		||||
          this.actionNotice = res.data.actionNotice === '1'
 | 
			
		||||
          this.dynamicNotice = res.data.dynamicNotice === '1'
 | 
			
		||||
 | 
			
		||||
          if (res.data.periodValidityType === '1') {
 | 
			
		||||
            this.periodValidityEndTime = res.data.periodValidityEndTime
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }).catch(msg => {
 | 
			
		||||
        this.$u.toast(msg)
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    publish() {
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/release`, null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          commitType: this.commitType,
 | 
			
		||||
          periodValidityType: this.periodValidityType,
 | 
			
		||||
          actionNotice: this.actionNotice ? '1' : '0',
 | 
			
		||||
          dynamicNotice: this.dynamicNotice ? '1' : '0',
 | 
			
		||||
          shareStatus: '0',
 | 
			
		||||
          wechatId: '0',
 | 
			
		||||
          id: this.id,
 | 
			
		||||
          periodValidityEndTime: this.periodValidityType === '1' ? this.periodValidityEndTime : ''
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          uni.$emit('reload')
 | 
			
		||||
          this.$u.toast('发布成功')
 | 
			
		||||
 | 
			
		||||
          this.back()
 | 
			
		||||
        }
 | 
			
		||||
      }).catch(e => {
 | 
			
		||||
        this.$u.toast(e)
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    confirm() {
 | 
			
		||||
      if (this.type === 'edit') {
 | 
			
		||||
        this.publish()
 | 
			
		||||
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      uni.$emit('setting', {
 | 
			
		||||
        periodValidityType: this.periodValidityType,
 | 
			
		||||
        commitType: this.commitType,
 | 
			
		||||
        actionNotice: this.actionNotice ? '1' : '0',
 | 
			
		||||
        dynamicNotice: this.dynamicNotice ? '1' : '0',
 | 
			
		||||
        periodValidityEndTime: this.periodValidityEndTime ? this.periodValidityEndTime : ''
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      this.back()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.form-setting {
 | 
			
		||||
  padding: 0 20px;
 | 
			
		||||
 | 
			
		||||
  .add-form__footer {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    z-index: 1;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
 | 
			
		||||
    div {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      &:first-child:active {
 | 
			
		||||
        background: #eee;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        color: #fff;
 | 
			
		||||
        font-size: 36px;
 | 
			
		||||
        background: #3192F4;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          opacity: 0.8;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
        line-height: 112px;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          background: #eee;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  * {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  & > h2 {
 | 
			
		||||
    height: 80px;
 | 
			
		||||
    padding-top: 24px;
 | 
			
		||||
    font-size: 28px;
 | 
			
		||||
    color: #999999;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .form-setting__list {
 | 
			
		||||
    padding: 0 20px;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    border-radius: 8px;
 | 
			
		||||
 | 
			
		||||
    .setting-item {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: space-between;
 | 
			
		||||
      height: 104px;
 | 
			
		||||
      border-bottom: 1px solid #D8DDE6;
 | 
			
		||||
 | 
			
		||||
      .setting-item__right {
 | 
			
		||||
        color: #999;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
 | 
			
		||||
        span {
 | 
			
		||||
          margin-right: 6px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ::v-deep .u-radio__label {
 | 
			
		||||
          color: #999;
 | 
			
		||||
          font-size: 28px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ::v-deep .u-radio {
 | 
			
		||||
          &:last-child {
 | 
			
		||||
            .u-radio__label {
 | 
			
		||||
              margin-right: 6px;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        border: none;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > div {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .setting-item__left {
 | 
			
		||||
        color: #666666;
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
 | 
			
		||||
        image {
 | 
			
		||||
          width: 30px;
 | 
			
		||||
          height: 30px;
 | 
			
		||||
          margin-left: 16px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										518
									
								
								src/apps/AppAskForm/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										518
									
								
								src/apps/AppAskForm/components/List.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,518 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="form">
 | 
			
		||||
    <AiTopFixed>
 | 
			
		||||
      <u-search placeholder="请输入标题" :show-action="false" search-icon-color="#ccc" v-model="search.title"
 | 
			
		||||
                @search="isMore = false, search.current = 1, getList()"/>
 | 
			
		||||
    </AiTopFixed>
 | 
			
		||||
    <scroll-view show-scrollbar scroll-y @scrolltolower="getList" class="form-list">
 | 
			
		||||
      <div class="form-item" v-for="(item, index) in list" :key="index"
 | 
			
		||||
           @click="showPopup(item)">
 | 
			
		||||
        <div class="form-item__top">
 | 
			
		||||
          <div class="form-item__left">
 | 
			
		||||
            <h2>{{ item.title }}</h2>
 | 
			
		||||
            <div class="form-item__left--info">
 | 
			
		||||
              <span v-text="item.createUnitName"/>
 | 
			
		||||
              <span v-text="item.createUserName"/>
 | 
			
		||||
              <span>{{ item.createTime.substr(0, item.createTime.length - 3) }}</span>
 | 
			
		||||
              <span>{{ $dict.getLabel('questionnaireType', item.type) }}</span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="form-item__right">
 | 
			
		||||
            <h2>{{ item.dataCount }}</h2>
 | 
			
		||||
            <span>答卷数量</span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="form-item__bottom form-item__bottom--active">
 | 
			
		||||
          <i :style="{background: $dict.getColor('questionnaireStatus', item.status)}"></i>
 | 
			
		||||
          <span>{{ $dict.getLabel('questionnaireStatus', item.status) }}</span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <u-gap/>
 | 
			
		||||
      <AiEmpty v-if="!list.length && isMore"></AiEmpty>
 | 
			
		||||
    </scroll-view>
 | 
			
		||||
    <u-popup v-model="isShow" :closeable="false" mode="bottom" :z-index="11">
 | 
			
		||||
      <div class="popup">
 | 
			
		||||
        <h2>{{ info.title }}</h2>
 | 
			
		||||
        <div class="operate-list">
 | 
			
		||||
          <div class="operate-item" @click="toEdit">
 | 
			
		||||
            <div>
 | 
			
		||||
              <image :src="`${$cdn}askform/bj.png`"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <h3>编辑</h3>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="operate-item" @click="linkTo('/pages/mainEntry?app=AppForm&preview=1&id=' + id)">
 | 
			
		||||
            <div>
 | 
			
		||||
              <image :src="`${$cdn}askform/yl.png`"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <h3>预览</h3>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="operate-item" @click="publish" v-if="info.status !== '1'">
 | 
			
		||||
            <div>
 | 
			
		||||
              <image :src="`${$cdn}askform/fb.png`"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <h3>发布</h3>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="operate-item" @click="isShowModal = true" v-if="info.status === '1'">
 | 
			
		||||
            <div>
 | 
			
		||||
              <image :src="`${$cdn}askform/stop.png`"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <h3>停止</h3>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="operate-item" @click="showShare">
 | 
			
		||||
            <div>
 | 
			
		||||
              <image :src="`${$cdn}askform/fx.png`"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <h3>分享</h3>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="operate-item" @click="share(id)">
 | 
			
		||||
            <div>
 | 
			
		||||
              <image :src="`${$cdn}askform/mb.png`"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <h3>共享为模板</h3>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="operate-item" @click="remove(id)">
 | 
			
		||||
            <div>
 | 
			
		||||
              <image :src="`${$cdn}askform/sc.png`"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <h3>删除</h3>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="popup-btn" @click="isShow = false">关闭</div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </u-popup>
 | 
			
		||||
    <u-modal v-model="isShowModal" show-cancel-button content="确定停止该表单?" @confirm="toStop"></u-modal>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions} from 'vuex'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'formList',
 | 
			
		||||
  label: '表单列表',
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      search: {
 | 
			
		||||
        current: 1,
 | 
			
		||||
        templateType: 0,
 | 
			
		||||
        title: ''
 | 
			
		||||
      },
 | 
			
		||||
      isShowModal: false,
 | 
			
		||||
      value: '',
 | 
			
		||||
      id: '',
 | 
			
		||||
      info: {},
 | 
			
		||||
      isMore: false,
 | 
			
		||||
      list: [],
 | 
			
		||||
      isShow: false
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.$loading()
 | 
			
		||||
    this.$dict.load(['questionnaireStatus', 'questionnaireType', 'questionnaireFieldType']).then(() => {
 | 
			
		||||
      this.getList()
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['wxInvoke']),
 | 
			
		||||
    linkTo(url) {
 | 
			
		||||
      this.isShow = false
 | 
			
		||||
 | 
			
		||||
      uni.navigateTo({
 | 
			
		||||
        url
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    showPopup(item) {
 | 
			
		||||
      if (item.status === '2') {
 | 
			
		||||
        this.$confirm('表单已停止发布,请在后台管理系统中查看调查结果', '', {
 | 
			
		||||
          showCancel: false
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.info = item
 | 
			
		||||
      this.id = item.id
 | 
			
		||||
      this.isShow = true
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    toStop() {
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/stopRelease?id=${this.info.id}`).then(res => {
 | 
			
		||||
        if (res.code === 0) {
 | 
			
		||||
          this.$u.toast('停止成功')
 | 
			
		||||
          this.search.current = 1
 | 
			
		||||
          this.isShow = false
 | 
			
		||||
          this.isMore = false
 | 
			
		||||
          this.getList()
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    showShare() {
 | 
			
		||||
      if (this.info.status !== '1') {
 | 
			
		||||
        this.isShow = false
 | 
			
		||||
        return this.$u.toast(`该表单${this.info.status === '0' ? '未发布' : '已截止'},无法分享!`)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      uni.showActionSheet({
 | 
			
		||||
        itemList: ['分享', '微信分享', '获取链接'],
 | 
			
		||||
        success: data => {
 | 
			
		||||
          this.$http.post(`/app/appquestionnairetemplate/queryQrCode?id=${this.info.id}`).then(res => {
 | 
			
		||||
            if (res.code == 0) {
 | 
			
		||||
              if (data.tapIndex === 2) {
 | 
			
		||||
                this.copy(res.data.linkUrl)
 | 
			
		||||
                this.isShow = false
 | 
			
		||||
              }
 | 
			
		||||
              if (data.tapIndex === 0 || data.tapIndex === 1) {
 | 
			
		||||
                if (data.tapIndex === 0) {
 | 
			
		||||
                  this.wxInvoke(['shareAppMessage', {
 | 
			
		||||
                    title: this.info.title,
 | 
			
		||||
                    desc: this.info.tableExplain,
 | 
			
		||||
                    link: res.data.linkUrl,
 | 
			
		||||
                    imgUrl: this.info.headPicture
 | 
			
		||||
                  }, () => {
 | 
			
		||||
                    this.isShow = false
 | 
			
		||||
                  }])
 | 
			
		||||
                } else {
 | 
			
		||||
                  this.wxInvoke(['shareWechatMessage', {
 | 
			
		||||
                    title: this.info.title,
 | 
			
		||||
                    desc: this.info.tableExplain,
 | 
			
		||||
                    link: res.data.linkUrl,
 | 
			
		||||
                    imgUrl: this.info.headPicture
 | 
			
		||||
                  }, () => {
 | 
			
		||||
                    this.isShow = false
 | 
			
		||||
                  }])
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    copy(link) {
 | 
			
		||||
      let oInput = document.createElement('input')
 | 
			
		||||
      oInput.value = link
 | 
			
		||||
      document.body.appendChild(oInput)
 | 
			
		||||
      oInput.select()
 | 
			
		||||
      document.execCommand('Copy')
 | 
			
		||||
      this.$u.toast('已复制')
 | 
			
		||||
      oInput.remove()
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    publish() {
 | 
			
		||||
      if (this.info.status === '1') {
 | 
			
		||||
        return this.$u.toast('该表单已发布')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.linkTo(`/pages/askForm/formSetting?id=${this.info.id}&type=edit`)
 | 
			
		||||
      this.isShow = false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    toEdit() {
 | 
			
		||||
      if (this.info.dataCount !== 0) {
 | 
			
		||||
        return this.$u.toast('该表单已有数据,无法编辑!')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$emit('change', {
 | 
			
		||||
        type: 'AddForm',
 | 
			
		||||
        params: {
 | 
			
		||||
          id: this.id
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      this.isShow = false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    share(id) {
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/share?id=${id}`).then(res => {
 | 
			
		||||
        if (res.code === 0) {
 | 
			
		||||
          this.$confirm('调查表单共享成功,其他成员可在新建项目时直接使用!', '', {
 | 
			
		||||
            showCancel: false
 | 
			
		||||
          })
 | 
			
		||||
          this.isShow = false
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    remove(id) {
 | 
			
		||||
      if (this.info.dataCount !== 0) {
 | 
			
		||||
        return this.$u.toast('该表单已有数据,无法删除!')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$confirm('确定删除该数据?').then(() => {
 | 
			
		||||
        this.$http.post(`/app/appquestionnairetemplate/delete?id=${id}`).then(res => {
 | 
			
		||||
          if (res.code == 0) {
 | 
			
		||||
            this.$u.toast('删除成功')
 | 
			
		||||
            this.isShow = false
 | 
			
		||||
            this.search.current = 1
 | 
			
		||||
            this.isMore = false
 | 
			
		||||
 | 
			
		||||
            this.getList()
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }).catch(() => {
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    reload() {
 | 
			
		||||
      this.isMore = false
 | 
			
		||||
      this.search.current = 1
 | 
			
		||||
 | 
			
		||||
      this.getList()
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getList() {
 | 
			
		||||
      if (this.isMore) return
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/list`, null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          ...this.search,
 | 
			
		||||
          size: 10
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          if (this.search.current > 1) {
 | 
			
		||||
            this.list = [...this.list, ...res.data.records]
 | 
			
		||||
          } else {
 | 
			
		||||
            this.list = res.data.records
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          uni.hideLoading()
 | 
			
		||||
 | 
			
		||||
          if (res.data.records.length < 10) {
 | 
			
		||||
            this.isMore = true
 | 
			
		||||
 | 
			
		||||
            return false
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          this.search.current = this.search.current + 1
 | 
			
		||||
        } else {
 | 
			
		||||
          uni.hideLoading()
 | 
			
		||||
        }
 | 
			
		||||
      }).catch(() => {
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.form {
 | 
			
		||||
  height: 100vh;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
 | 
			
		||||
  ::v-deep .u-search {
 | 
			
		||||
    margin-bottom: 0 !important;
 | 
			
		||||
 | 
			
		||||
    .u-search__content__input {
 | 
			
		||||
      height: 100%;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .form-list {
 | 
			
		||||
    height: calc(100vh - 98rpx - 100rpx);
 | 
			
		||||
    background: #f5f5f5;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .popup {
 | 
			
		||||
    background: #F7F7F7;
 | 
			
		||||
 | 
			
		||||
    & > h2 {
 | 
			
		||||
      height: 72px;
 | 
			
		||||
      line-height: 72px;
 | 
			
		||||
      padding: 0 20px;
 | 
			
		||||
      color: #999999;
 | 
			
		||||
      font-size: 22px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      border-bottom: 2px solid #D7D8DA;
 | 
			
		||||
      overflow: hidden;
 | 
			
		||||
      text-overflow: ellipsis;
 | 
			
		||||
      white-space: nowrap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .popup-btn {
 | 
			
		||||
      height: 96px;
 | 
			
		||||
      line-height: 96px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      font-size: 30px;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      &:active {
 | 
			
		||||
        background: #eee;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .operate-list {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-wrap: wrap;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      padding-bottom: 26px;
 | 
			
		||||
 | 
			
		||||
      .operate-item {
 | 
			
		||||
        width: 25%;
 | 
			
		||||
        font-size: 0;
 | 
			
		||||
        margin-top: 28px;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          opacity: 0.7;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        h3 {
 | 
			
		||||
          margin-top: 20px;
 | 
			
		||||
          color: #666666;
 | 
			
		||||
          font-size: 26px;
 | 
			
		||||
          font-weight: normal;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      image {
 | 
			
		||||
        width: 100px;
 | 
			
		||||
        height: 100px;
 | 
			
		||||
        border-radius: 16px;
 | 
			
		||||
        background: #fff;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  div {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .form-item {
 | 
			
		||||
    margin: 24px 25px 0;
 | 
			
		||||
    padding: 32px;
 | 
			
		||||
    background: #FFFFFF;
 | 
			
		||||
    border-radius: 16px;
 | 
			
		||||
 | 
			
		||||
    .form-item__bottom {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      margin-top: 28px;
 | 
			
		||||
      color: #999999;
 | 
			
		||||
 | 
			
		||||
      i {
 | 
			
		||||
        width: 12px;
 | 
			
		||||
        height: 12px;
 | 
			
		||||
        margin-right: 6px;
 | 
			
		||||
        border-radius: 50%;
 | 
			
		||||
        background: #999999;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        font-size: 26px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &.form-item__bottom--active i {
 | 
			
		||||
        background: #3CB300;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .form-item__top {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      justify-content: space-between;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
 | 
			
		||||
      .form-item__right {
 | 
			
		||||
        text-align: center;
 | 
			
		||||
 | 
			
		||||
        h2 {
 | 
			
		||||
          line-height: 40px;
 | 
			
		||||
          margin-bottom: 16px;
 | 
			
		||||
          font-size: 32px;
 | 
			
		||||
          font-weight: 600;
 | 
			
		||||
          color: #1EA0FA;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        span {
 | 
			
		||||
          color: #999999;
 | 
			
		||||
          font-size: 22px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .form-item__left {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        max-width: 80%;
 | 
			
		||||
        position: relative;
 | 
			
		||||
 | 
			
		||||
        &::after {
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          right: -15px;
 | 
			
		||||
          top: 50%;
 | 
			
		||||
          width: 2px;
 | 
			
		||||
          height: 96px;
 | 
			
		||||
          background: #F5F5F5;
 | 
			
		||||
          content: '';
 | 
			
		||||
          transform: translateY(-50%);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        h2 {
 | 
			
		||||
          line-height: 44px;
 | 
			
		||||
          margin-bottom: 16px;
 | 
			
		||||
          color: #333;
 | 
			
		||||
          font-size: 32px;
 | 
			
		||||
          font-weight: 700;
 | 
			
		||||
          overflow: hidden;
 | 
			
		||||
          text-overflow: ellipsis;
 | 
			
		||||
          white-space: nowrap;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .form-item__left--info {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
          flex-wrap: wrap;
 | 
			
		||||
          color: #999;
 | 
			
		||||
          font-size: 20px;
 | 
			
		||||
 | 
			
		||||
          span, div {
 | 
			
		||||
            position: relative;
 | 
			
		||||
            margin-right: 24px;
 | 
			
		||||
 | 
			
		||||
            &::after {
 | 
			
		||||
              position: absolute;
 | 
			
		||||
              right: -12px;
 | 
			
		||||
              top: 50%;
 | 
			
		||||
              width: 2px;
 | 
			
		||||
              height: 20px;
 | 
			
		||||
              background: #D1D2D5;
 | 
			
		||||
              content: '';
 | 
			
		||||
              transform: translateY(-50%);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            &:last-child {
 | 
			
		||||
              margin-right: 0;
 | 
			
		||||
 | 
			
		||||
              &::after {
 | 
			
		||||
                display: none;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .type-0 {
 | 
			
		||||
    background: #2266FF !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .type-1 {
 | 
			
		||||
    background: rgba(34, 170, 153, 1) !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .type-2 {
 | 
			
		||||
    background: rgba(248, 180, 37, 1) !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .type-3 {
 | 
			
		||||
    background: rgba(102, 119, 187, 1) !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .type-4 {
 | 
			
		||||
    background: rgba(236, 68, 97, 1) !important;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										457
									
								
								src/apps/AppAskForm/components/PreviewForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										457
									
								
								src/apps/AppAskForm/components/PreviewForm.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,457 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="add-form">
 | 
			
		||||
    <div class="header-pic">
 | 
			
		||||
      <image v-if="form.headPicture" :src="form.headPicture"/>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="form-info">
 | 
			
		||||
      <div class="form-info__wrapper">
 | 
			
		||||
        <textarea class="title" :auto-height="true" disabled placeholder="请输入标题 (必填)" v-model="form.title"></textarea>
 | 
			
		||||
        <u-input class="content" disabled :clearable="false" type="textarea" v-model="form.tableExplain"
 | 
			
		||||
                 placeholder="请输入表单描述 (选填)" :height="80" :auto-height="true" :maxlength="255"></u-input>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="components-list">
 | 
			
		||||
      <div class="components-item" v-for="(item, index) in targetList" :key="index">
 | 
			
		||||
        <div class="components-item__title">
 | 
			
		||||
          <div class="components-item__title--left">
 | 
			
		||||
            <em :style="{opacity: item.required ? 1 : 0}">*</em>
 | 
			
		||||
            <i>{{ index + 1 }}.</i>
 | 
			
		||||
            <h2>{{ item.label }}</h2>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="components-item__filed">
 | 
			
		||||
          <template v-if="(item.type === 'radio')">
 | 
			
		||||
            <u-radio-group v-model="item.value" wrap>
 | 
			
		||||
              <u-radio :name="field.label" v-for="(field, i) in item.options" :key="i">
 | 
			
		||||
                <image :src="field.img[0].url" v-if="field.img.length"/>
 | 
			
		||||
                <span>{{ field.label }}</span>
 | 
			
		||||
              </u-radio>
 | 
			
		||||
            </u-radio-group>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-if="(item.type === 'checkbox')">
 | 
			
		||||
            <u-checkbox-group wrap>
 | 
			
		||||
              <u-checkbox :name="field.label" v-model="field.checked1" v-for="(field, i) in item.options" :key="i">
 | 
			
		||||
                <image :src="field.img[0].url" v-if="field.img.length"/>
 | 
			
		||||
                <span>{{ field.label }}</span>
 | 
			
		||||
              </u-checkbox>
 | 
			
		||||
            </u-checkbox-group>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-if="(item.type === 'select')">
 | 
			
		||||
            <div class="components-item__select">
 | 
			
		||||
              <span>{{ item.placeholder }}</span>
 | 
			
		||||
              <u-icon name="arrow-down" color="#DEDFDF"/>
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-if="(item.type === 'upload')">
 | 
			
		||||
            <div class="components-item__select components-item__textarea components-item__upload">
 | 
			
		||||
              <image :src="`${$cdn}askform/upload.png`"/>
 | 
			
		||||
              <span>选择图片(2M以内)</span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-if="(item.type === 'input')">
 | 
			
		||||
            <div class="components-item__select">
 | 
			
		||||
              <span>{{ item.placeholder }}</span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-if="(item.type === 'textarea')">
 | 
			
		||||
            <div class="components-item__select components-item__textarea">
 | 
			
		||||
              <span>{{ item.placeholder }}</span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <AiBack custom @back="$emit('back')"/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  props: ['formData', 'targetListData'],
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      form: {
 | 
			
		||||
        tableExplain: '详细描述',
 | 
			
		||||
        title: '问卷调查',
 | 
			
		||||
        isShowheadPicture: true,
 | 
			
		||||
        isShowTableExplain: true,
 | 
			
		||||
        isShowBtn: true,
 | 
			
		||||
        headPicture: '',
 | 
			
		||||
        commitType: '1',
 | 
			
		||||
        periodValidityType: '0',
 | 
			
		||||
        actionNotice: '1',
 | 
			
		||||
        dynamicNotice: '1',
 | 
			
		||||
        periodValidityEndTime: '',
 | 
			
		||||
        shareStatus: '0',
 | 
			
		||||
        count: 0,
 | 
			
		||||
        wechatId: '0',
 | 
			
		||||
        type: 0,
 | 
			
		||||
        buttonExplain: '提交',
 | 
			
		||||
        tips: true
 | 
			
		||||
      },
 | 
			
		||||
      templateType: 0,
 | 
			
		||||
      targetList: [],
 | 
			
		||||
      isShow: false,
 | 
			
		||||
      type: 0,
 | 
			
		||||
      id: '',
 | 
			
		||||
      touchStart: 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.form = this.formData
 | 
			
		||||
    this.targetList = this.targetListData
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    getInfo(id) {
 | 
			
		||||
      uni.showLoading()
 | 
			
		||||
      this.$http.post(`/app/appquestionnairetemplate/queryDetailById?id=${id}`).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.form = {
 | 
			
		||||
            ...res.data,
 | 
			
		||||
            headPicture: res.data.headPicture
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          this.type = res.data.type
 | 
			
		||||
 | 
			
		||||
          this.targetList = res.data.fields.map(item => {
 | 
			
		||||
            return JSON.parse(item.fieldInfo)
 | 
			
		||||
          })
 | 
			
		||||
 | 
			
		||||
          this.pageShow = true
 | 
			
		||||
        } else {
 | 
			
		||||
          this.$u.toast(res.msg)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
      }).catch(() => {
 | 
			
		||||
        uni.hideLoading()
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.add-form {
 | 
			
		||||
  min-height: 100vh;
 | 
			
		||||
  padding-bottom: 60px;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  background: #F3F6F9;
 | 
			
		||||
 | 
			
		||||
  * {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .u-drawer-bottom {
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .components-list {
 | 
			
		||||
    padding: 0 20px;
 | 
			
		||||
 | 
			
		||||
    .components-item {
 | 
			
		||||
      margin-top: 24px;
 | 
			
		||||
      padding: 32px;
 | 
			
		||||
      box-shadow: 0 4px 8px 4px rgba(233, 233, 233, 0.39);
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
      overflow: hidden;
 | 
			
		||||
      border: 1px solid #EEEFF0;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      ::v-deep .u-radio, ::v-deep .u-checkbox {
 | 
			
		||||
        position: relative;
 | 
			
		||||
        margin-bottom: 20px;
 | 
			
		||||
 | 
			
		||||
        &:last-child {
 | 
			
		||||
          margin-bottom: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .u-checkbox__icon-wrap, .u-radio__icon-wrap {
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          top: 4px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .u-radio__label, .u-checkbox__label {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
          margin-right: 0;
 | 
			
		||||
          margin-left: 40px;
 | 
			
		||||
          line-height: 1.5;
 | 
			
		||||
          text-align: justify;
 | 
			
		||||
 | 
			
		||||
          image {
 | 
			
		||||
            width: 100px;
 | 
			
		||||
            height: 100px;
 | 
			
		||||
            margin: 0 10px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        color: #666;
 | 
			
		||||
        font-size: 26px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .components-item__select {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: space-between;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 80px;
 | 
			
		||||
        margin-bottom: 8px;
 | 
			
		||||
        padding: 0 26px;
 | 
			
		||||
        border: 1px solid #DEDFDF;
 | 
			
		||||
 | 
			
		||||
        &.components-item__textarea {
 | 
			
		||||
          align-items: flex-start;
 | 
			
		||||
          height: 160px;
 | 
			
		||||
          padding-top: 20px;
 | 
			
		||||
 | 
			
		||||
          image {
 | 
			
		||||
            width: 46px;
 | 
			
		||||
            height: 34px;
 | 
			
		||||
            margin-right: 16px;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          span {
 | 
			
		||||
            color: #666;
 | 
			
		||||
            font-size: 26px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &.components-item__upload {
 | 
			
		||||
          justify-content: center;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .components-item__title {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: space-between;
 | 
			
		||||
        margin-bottom: 32px;
 | 
			
		||||
 | 
			
		||||
        em {
 | 
			
		||||
          margin-right: 4px;
 | 
			
		||||
          font-style: normal;
 | 
			
		||||
          color: rgb(226, 33, 32);;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        image {
 | 
			
		||||
          width: 32px;
 | 
			
		||||
          height: 32px;
 | 
			
		||||
          box-sizing: content-box;
 | 
			
		||||
          padding: 20px 0 20px 20px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        div {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: baseline;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
          font-size: 32px;
 | 
			
		||||
 | 
			
		||||
          i {
 | 
			
		||||
            font-style: normal;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          h2 {
 | 
			
		||||
            font-weight: 600;
 | 
			
		||||
            font-size: 32px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .add-popup {
 | 
			
		||||
    height: 440px;
 | 
			
		||||
    border-radius: 20px 20px 0 0;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
 | 
			
		||||
    .add-popup__title {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      position: relative;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      height: 96px;
 | 
			
		||||
      border-bottom: 1px solid #E4E5E6;
 | 
			
		||||
 | 
			
		||||
      h2 {
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        font-weight: 600;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      image {
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        right: 32px;
 | 
			
		||||
        top: 50%;
 | 
			
		||||
        width: 30px;
 | 
			
		||||
        height: 20px;
 | 
			
		||||
        transform: translateY(-50%);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .add-popup__list {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-wrap: wrap;
 | 
			
		||||
      padding: 0 34px;
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        width: calc((100% - 64px) / 3);
 | 
			
		||||
        height: 78px;
 | 
			
		||||
        line-height: 78px;
 | 
			
		||||
        margin-top: 32px;
 | 
			
		||||
        margin-right: 32px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        border-radius: 8px;
 | 
			
		||||
        border: 1px solid #E4E5E6;
 | 
			
		||||
 | 
			
		||||
        &:nth-of-type(3n) {
 | 
			
		||||
          margin-right: 0;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .add-form__footer {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    z-index: 1;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
 | 
			
		||||
    div {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        color: #fff;
 | 
			
		||||
        font-size: 36px;
 | 
			
		||||
        background: #3192F4;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          opacity: 0.8;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      span {
 | 
			
		||||
        flex: 1;
 | 
			
		||||
        height: 100%;
 | 
			
		||||
        line-height: 112px;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
 | 
			
		||||
        &:active {
 | 
			
		||||
          background: #eee;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .add-form__btn {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    width: 214px;
 | 
			
		||||
    height: 66px;
 | 
			
		||||
    line-height: 66px;
 | 
			
		||||
    margin: 64px auto 0;
 | 
			
		||||
    background: #FFFFFF;
 | 
			
		||||
    border-radius: 34px;
 | 
			
		||||
 | 
			
		||||
    &:active {
 | 
			
		||||
      opacity: 0.8;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    image {
 | 
			
		||||
      width: 28px;
 | 
			
		||||
      height: 28px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    span {
 | 
			
		||||
      margin-left: 16px;
 | 
			
		||||
      color: #4392E6;
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  * {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .form-info {
 | 
			
		||||
    margin-top: 26px;
 | 
			
		||||
    padding: 0 20px;
 | 
			
		||||
 | 
			
		||||
    & > h2 {
 | 
			
		||||
      height: 76px;
 | 
			
		||||
      line-height: 76px;
 | 
			
		||||
      color: #999999;
 | 
			
		||||
      font-weight: normal;
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .form-info__wrapper {
 | 
			
		||||
      padding: 0 18px;
 | 
			
		||||
      background: #fff;
 | 
			
		||||
 | 
			
		||||
      .title {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        padding: 22px 0;
 | 
			
		||||
        font-size: 36px;
 | 
			
		||||
        border-bottom: 1px solid #F1F2F3;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .content {
 | 
			
		||||
        padding: 30px 0 !important;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
 | 
			
		||||
        ::v-deep textarea {
 | 
			
		||||
          color: #333;
 | 
			
		||||
          font-size: 28px !important;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .header-pic {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    font-size: 0;
 | 
			
		||||
 | 
			
		||||
    span {
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      bottom: 16px;
 | 
			
		||||
      right: 16px;
 | 
			
		||||
      z-index: 1;
 | 
			
		||||
      width: 148px;
 | 
			
		||||
      height: 56px;
 | 
			
		||||
      line-height: 56px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      color: #fff;
 | 
			
		||||
      font-size: 26px;
 | 
			
		||||
      background: rgba(0, 0, 0, 0.16);
 | 
			
		||||
      border-radius: 28px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    image {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      height: 320px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										165
									
								
								src/apps/AppAskForm/components/Result.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								src/apps/AppAskForm/components/Result.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="result">
 | 
			
		||||
    <image class="result-success" :src="`${$cdn}form/result-success.png`"/>
 | 
			
		||||
    <h2>创建成功</h2>
 | 
			
		||||
    <p>表单创建成功,您现在可以把表单分享给更多的好友,来填写数据!</p>
 | 
			
		||||
    <div class="result-btn" @click="confirm">确定</div>
 | 
			
		||||
    <div class="result-footer">
 | 
			
		||||
      <div class="result-footer__item" @click="copy">
 | 
			
		||||
        <div>
 | 
			
		||||
          <image :src="`${$cdn}form/form-copylink.png`"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <h3>复制链接</h3>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="result-footer__item" @click="shareWechat">
 | 
			
		||||
        <div>
 | 
			
		||||
          <image :src="`${$cdn}form/form-wechat.png`"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <h3>微信好友</h3>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="result-footer__item" @click="share">
 | 
			
		||||
        <div>
 | 
			
		||||
          <image :src="`${$cdn}form/form-share.png`"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <h3>分享</h3>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions} from 'vuex'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Result',
 | 
			
		||||
 | 
			
		||||
  props: ['params'],
 | 
			
		||||
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.injectJWeixin(['sendChatMessage', 'selectEnterpriseContact'])
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['injectJWeixin', 'wxInvoke']),
 | 
			
		||||
 | 
			
		||||
    copy() {
 | 
			
		||||
      let oInput = document.createElement('input')
 | 
			
		||||
      oInput.value = this.params.linkUrl
 | 
			
		||||
      document.body.appendChild(oInput)
 | 
			
		||||
      oInput.select()
 | 
			
		||||
      document.execCommand('Copy')
 | 
			
		||||
      this.$u.toast('已复制')
 | 
			
		||||
      oInput.remove()
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    share() {
 | 
			
		||||
      this.injectJWeixin(['shareAppMessage', 'shareWechatMessage']).then(() => {
 | 
			
		||||
        this.wxInvoke(['shareAppMessage', {
 | 
			
		||||
          title: this.params.title,
 | 
			
		||||
          desc: this.params.tableExplain,
 | 
			
		||||
          link: this.params.linkUrl,
 | 
			
		||||
          imgUrl: this.params.headPicture
 | 
			
		||||
        }])
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    shareWechat() {
 | 
			
		||||
      this.injectJWeixin(['shareAppMessage', 'shareWechatMessage']).then(() => {
 | 
			
		||||
        this.wxInvoke(['shareWechatMessage', {
 | 
			
		||||
          title: this.params.title,
 | 
			
		||||
          desc: this.params.tableExplain,
 | 
			
		||||
          link: this.params.linkUrl,
 | 
			
		||||
          imgUrl: this.params.headPicture
 | 
			
		||||
        }])
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    confirm() {
 | 
			
		||||
      this.$emit('change', {
 | 
			
		||||
        type: 'Tabbar'
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  onShow() {
 | 
			
		||||
    wx.hideOptionMenu();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.result {
 | 
			
		||||
  min-height: 100vh;
 | 
			
		||||
  padding: 96px 96px 0;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
 | 
			
		||||
  .result-footer {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    margin-top: 96px;
 | 
			
		||||
 | 
			
		||||
    .result-footer__item {
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
 | 
			
		||||
      div {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        width: 100px;
 | 
			
		||||
        height: 100px;
 | 
			
		||||
        margin: 0 auto 16px;
 | 
			
		||||
        border-radius: 50%;
 | 
			
		||||
        background: #F4F6FA;
 | 
			
		||||
 | 
			
		||||
        image {
 | 
			
		||||
          width: 100px;
 | 
			
		||||
          height: 100px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      h3 {
 | 
			
		||||
        color: #666666;
 | 
			
		||||
        font-size: 24px;
 | 
			
		||||
        font-weight: normal;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .result-success {
 | 
			
		||||
    display: block;
 | 
			
		||||
    width: 192px;
 | 
			
		||||
    height: 192px;
 | 
			
		||||
    margin: 0 auto 16px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  p {
 | 
			
		||||
    margin: 16px 0 32px;
 | 
			
		||||
    color: #999999;
 | 
			
		||||
    font-size: 30px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .result-btn {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 88px;
 | 
			
		||||
    line-height: 88px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    font-size: 36px;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background: #197DF0;
 | 
			
		||||
    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.02);
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
 | 
			
		||||
    &:active {
 | 
			
		||||
      opacity: 0.8;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  h2 {
 | 
			
		||||
    color: #333333;
 | 
			
		||||
    font-size: 36px;
 | 
			
		||||
    font-weight: 700;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										61
									
								
								src/apps/AppAskForm/components/Tabbar.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/apps/AppAskForm/components/Tabbar.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="form-wrapper">
 | 
			
		||||
    <div class="form-content">
 | 
			
		||||
      <add-list ref="addList" v-if="currIndex === 1" @change="onChange"></add-list>
 | 
			
		||||
      <list ref="list" v-if="currIndex === 0" @change="onChange"></list>
 | 
			
		||||
    </div>
 | 
			
		||||
    <AiTabbar :active.sync="currIndex" :list="tabBar"/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import AddList from './AddList.vue'
 | 
			
		||||
import List from './List.vue'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'AppAskForm',
 | 
			
		||||
  appName: '问卷表单',
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      currIndex: 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  components: {
 | 
			
		||||
    AddList,
 | 
			
		||||
    List
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  computed: {
 | 
			
		||||
    tabBar() {
 | 
			
		||||
      const link = icon => `${this.$cdn}askform/${icon}.png`
 | 
			
		||||
      return [
 | 
			
		||||
        {text: "表单列表", iconPath: "bdlb1", selectedIconPath: "bdlb2"},
 | 
			
		||||
        {text: "新建项目", iconPath: "xjxm1", selectedIconPath: "xjxm2"}
 | 
			
		||||
      ].map(e => ({
 | 
			
		||||
        ...e,
 | 
			
		||||
        iconPath: link(e.iconPath),
 | 
			
		||||
        selectedIconPath: link(e.selectedIconPath)
 | 
			
		||||
      }))
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    onChange(e) {
 | 
			
		||||
      this.$emit('change', e)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onReachBottom() {
 | 
			
		||||
    if (this.currIndex === 0) {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.form-wrapper {
 | 
			
		||||
  // padding-bottom: 98px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										163
									
								
								src/apps/AppAskForm/components/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								src/apps/AppAskForm/components/config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
export const components = [
 | 
			
		||||
  {
 | 
			
		||||
    type: 'radio',
 | 
			
		||||
    label: '单选',
 | 
			
		||||
    fixedLabel: '单选',
 | 
			
		||||
    value: '',
 | 
			
		||||
    points: '',
 | 
			
		||||
    icon: 'iconradio',
 | 
			
		||||
    isShowPoints: false,
 | 
			
		||||
    required: true,
 | 
			
		||||
    hasAnswer: false,
 | 
			
		||||
    answer: '',
 | 
			
		||||
    pointType: '0',
 | 
			
		||||
    pointDict: [
 | 
			
		||||
      {
 | 
			
		||||
        dictName: '此题有唯一答案和分值',
 | 
			
		||||
        dictValue: '0'
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        dictName: '每个选项都有对应分值',
 | 
			
		||||
        dictValue: '1'
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    options: [
 | 
			
		||||
      {
 | 
			
		||||
        label: '选项1',
 | 
			
		||||
        value: '',
 | 
			
		||||
        point: '',
 | 
			
		||||
        img: []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        label: '选项2',
 | 
			
		||||
        value: '',
 | 
			
		||||
        point: '',
 | 
			
		||||
        img: []
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    title: ''
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    type: 'checkbox',
 | 
			
		||||
    label: '多选',
 | 
			
		||||
    fixedLabel: '多选',
 | 
			
		||||
    points: '',
 | 
			
		||||
    icon: 'iconcheck_box',
 | 
			
		||||
    isShowPoints: false,
 | 
			
		||||
    required: true,
 | 
			
		||||
    hasAnswer: false,
 | 
			
		||||
    answer: [],
 | 
			
		||||
    value: [],
 | 
			
		||||
    pointType: '0',
 | 
			
		||||
    pointDict: [
 | 
			
		||||
      {
 | 
			
		||||
        dictName: '此题有唯一答案和分值',
 | 
			
		||||
        dictValue: '0'
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        dictName: '每个选项都有对应分值',
 | 
			
		||||
        dictValue: '1'
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        dictName: '答对几项得几分,答错不得分',
 | 
			
		||||
        dictValue: '2'
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    options: [
 | 
			
		||||
      {
 | 
			
		||||
        label: '选项1',
 | 
			
		||||
        value: '',
 | 
			
		||||
        point: '',
 | 
			
		||||
        img: [],
 | 
			
		||||
        checked: false
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        label: '选项2',
 | 
			
		||||
        point: '',
 | 
			
		||||
        value: '',
 | 
			
		||||
        img: [],
 | 
			
		||||
        checked: false
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    title: ''
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    type: 'select',
 | 
			
		||||
    label: '单下拉框',
 | 
			
		||||
    fixedLabel: '单下拉框',
 | 
			
		||||
    value: '',
 | 
			
		||||
    points: '',
 | 
			
		||||
    icon: 'iconSelect',
 | 
			
		||||
    isShowPoints: false,
 | 
			
		||||
    required: true,
 | 
			
		||||
    hasAnswer: false,
 | 
			
		||||
    answer: '',
 | 
			
		||||
    pointType: '0',
 | 
			
		||||
    placeholder: '请选择',
 | 
			
		||||
    pointDict: [
 | 
			
		||||
      {
 | 
			
		||||
        dictName: '此题有唯一答案和分值',
 | 
			
		||||
        dictValue: '0'
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        dictName: '每个选项都有对应分值',
 | 
			
		||||
        dictValue: '1'
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    options: [
 | 
			
		||||
      {
 | 
			
		||||
        label: '选项1',
 | 
			
		||||
        value: '',
 | 
			
		||||
        point: '',
 | 
			
		||||
        img: []
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        label: '选项2',
 | 
			
		||||
        value: '',
 | 
			
		||||
        point: '',
 | 
			
		||||
        img: []
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    title: ''
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    type: 'input',
 | 
			
		||||
    label: '单行填空',
 | 
			
		||||
    fixedLabel: '单行填空',
 | 
			
		||||
    value: '',
 | 
			
		||||
    pointType: '0',
 | 
			
		||||
    icon: 'icontext_box',
 | 
			
		||||
    isShowPoints: false,
 | 
			
		||||
    points: '',
 | 
			
		||||
    required: true,
 | 
			
		||||
    hasAnswer: false,
 | 
			
		||||
    placeholder: '请输入...',
 | 
			
		||||
    answer: ''
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    type: 'textarea',
 | 
			
		||||
    label: '多行填空',
 | 
			
		||||
    fixedLabel: '多行填空',
 | 
			
		||||
    pointType: '0',
 | 
			
		||||
    icon: 'icontext_area',
 | 
			
		||||
    points: '',
 | 
			
		||||
    isShowPoints: false,
 | 
			
		||||
    required: true,
 | 
			
		||||
    hasAnswer: false,
 | 
			
		||||
    answer: '',
 | 
			
		||||
    placeholder: '请输入...',
 | 
			
		||||
    value: ''
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    type: 'upload',
 | 
			
		||||
    label: '上传图片',
 | 
			
		||||
    fixedLabel: '上传图片',
 | 
			
		||||
    value: '',
 | 
			
		||||
    icon: 'iconpic',
 | 
			
		||||
    isShowPoints: false,
 | 
			
		||||
    points: '',
 | 
			
		||||
    required: true,
 | 
			
		||||
    hasAnswer: false,
 | 
			
		||||
    answer: ''
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										341
									
								
								src/apps/AppAskForm/components/formDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								src/apps/AppAskForm/components/formDetail.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,341 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <section class="formDetail">
 | 
			
		||||
    <AiResult v-if="result.tips" v-bind="result">
 | 
			
		||||
      <template v-if="isExam" #extra>
 | 
			
		||||
        <div flex class="scorePane">
 | 
			
		||||
          <div>成绩</div>
 | 
			
		||||
          <div class="fill"><em v-html="score"/> 分</div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </template>
 | 
			
		||||
    </AiResult>
 | 
			
		||||
    <template v-else-if="form.id">
 | 
			
		||||
      <image v-if="form.headPicture" class="headPicture" :src="form.headPicture"/>
 | 
			
		||||
      <b class="title">{{ form.title || "标题" }}</b>
 | 
			
		||||
      <div class="tableExplain">{{ form.tableExplain }}</div>
 | 
			
		||||
      <u-form class="content" label-position="top">
 | 
			
		||||
        <u-form-item class="item" v-for="(op,i) in fields" :key="i" :label="(i+1)+'.'+op.fieldName"
 | 
			
		||||
                     :required="op.fieldInfo.required==1">
 | 
			
		||||
          <template v-if="op.fieldType=='input'">
 | 
			
		||||
            <input v-model="op.fieldValue" :placeholder="op.fieldInfo.placeholder" :disabled="isResult"/>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-else-if="op.fieldType=='textarea'">
 | 
			
		||||
            <textarea v-model="op.fieldValue" :disabled="isResult" :placeholder="op.fieldInfo.placeholder"/>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-else-if="op.fieldType=='upload'">
 | 
			
		||||
            <AiUploader @list="v=>op.fieldValue=v.map(e=>e.url)" :def="op.fieldValue" :disabled="isResult"
 | 
			
		||||
                        preview action="/admin/file/add2"/>
 | 
			
		||||
          </template>
 | 
			
		||||
          <u-row v-else-if="op.fieldType=='radio'">
 | 
			
		||||
            <radio-group @change="({detail})=>op.fieldValue=detail.value">
 | 
			
		||||
              <div class="option" flex v-for="option in op.fieldInfo.options" :key="option.label">
 | 
			
		||||
                <radio :value="option.label" :disabled="isResult" :checked="op.fieldValue==option.label"/>
 | 
			
		||||
                <AiImage v-if="option.img" :src="option.img" preview/>
 | 
			
		||||
                <div class="label fill">{{ option.label }}</div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </radio-group>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <u-row v-else-if="op.fieldType=='checkbox'">
 | 
			
		||||
            <checkbox-group @change="({detail})=>op.fieldValue=detail.value">
 | 
			
		||||
              <div class="option" flex v-for="option in op.fieldInfo.options" :key="option.label">
 | 
			
		||||
                <checkbox :value="option.label" :disabled="isResult"
 | 
			
		||||
                          :checked="option.checked"/>
 | 
			
		||||
                <AiImage v-if="option.img" :src="option.img" preview/>
 | 
			
		||||
                <div class="label fill">{{ option.label }}</div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </checkbox-group>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <template v-else-if="op.fieldType=='select'">
 | 
			
		||||
            <AiSelect @data="v=>op.fieldValue=v.map(e=>e.value)" :list="op.fieldInfo.options" :disabled="isResult">
 | 
			
		||||
              <div class="option" flex>
 | 
			
		||||
                <div class="label fill" v-if="op.fieldValue">{{ op.fieldValue.toString() }}</div>
 | 
			
		||||
                <i class="fill" v-else>请选择</i>
 | 
			
		||||
                <u-icon name="arrow-right" color="#ddd"/>
 | 
			
		||||
              </div>
 | 
			
		||||
            </AiSelect>
 | 
			
		||||
          </template>
 | 
			
		||||
        </u-form-item>
 | 
			
		||||
      </u-form>
 | 
			
		||||
      <div class="bottom" v-if="!(isPreview||isResult)">
 | 
			
		||||
        <div class="bottomBtn" @tap="handleSubmit">提交</div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <AiLoading v-else tips="调查问卷加载中..."/>
 | 
			
		||||
  </section>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
import {mapState} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "formDetail",
 | 
			
		||||
  inject: {root: {}},
 | 
			
		||||
  computed: {
 | 
			
		||||
    ...mapState(['openUser', 'token']),
 | 
			
		||||
    isExam() {
 | 
			
		||||
      return this.form?.type == 1
 | 
			
		||||
    },
 | 
			
		||||
    isResult() {
 | 
			
		||||
      return !!this.$route.query?.result
 | 
			
		||||
    },
 | 
			
		||||
    isPreview() {
 | 
			
		||||
      return !!this.$route.query?.preview
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      form: {},
 | 
			
		||||
      fields: [],
 | 
			
		||||
      checkUser: false,
 | 
			
		||||
      result: {},
 | 
			
		||||
      score: 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    form: {
 | 
			
		||||
      deep: true,
 | 
			
		||||
      handler(v) {
 | 
			
		||||
        this.fields = v?.fields?.map(e => {
 | 
			
		||||
          let fieldInfo = JSON.parse(e.fieldInfo)
 | 
			
		||||
          fieldInfo?.options?.map(op => {
 | 
			
		||||
            op.img = op?.img?.[0]?.url
 | 
			
		||||
            op.checked = !!e.fieldValue?.split(",")?.includes(op.label)
 | 
			
		||||
          })
 | 
			
		||||
          if (e.fieldType == 'select') {
 | 
			
		||||
            fieldInfo.options = fieldInfo.options.map(e => ({...e, value: e.label, label: e.label}))
 | 
			
		||||
          }
 | 
			
		||||
          return {...e, fieldInfo}
 | 
			
		||||
        }) || []
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    emitShow() {
 | 
			
		||||
      document.title = this.form.title || "调查问卷"
 | 
			
		||||
    },
 | 
			
		||||
    getForm() {
 | 
			
		||||
      let {id} = this.$route.query
 | 
			
		||||
      this.$http.post("/app/appquestionnairetemplate/queryDetailById", null, {
 | 
			
		||||
        withoutToken: true,
 | 
			
		||||
        params: {id}
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          this.form = res.data
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    getResult() {
 | 
			
		||||
      let {id} = this.$route.query
 | 
			
		||||
      this.$http.post("/app/appquestionnairetemplate/commitCheck", null, {
 | 
			
		||||
        params: {id}
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          this.form = res.data
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    validateForm() {
 | 
			
		||||
      return !this.fields.some(e => {
 | 
			
		||||
        if (!!e?.fieldInfo?.required && !e.fieldValue?.toString()) {
 | 
			
		||||
          this.$u.toast(e.fieldName + "不能为空!")
 | 
			
		||||
          return true
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleSubmit() {
 | 
			
		||||
      if (this.validateForm()) {
 | 
			
		||||
        this.handleScore()
 | 
			
		||||
        let {avatar: avatarUrl, openId, name: nickName, type: userType, unionId, corpName} = this.openUser
 | 
			
		||||
        this.$http.post("/app/appquestionnairetemplate/commit", {
 | 
			
		||||
          fields: this.fields.map(e => ({
 | 
			
		||||
            ...e,
 | 
			
		||||
            fieldInfo: JSON.stringify(e.fieldInfo),
 | 
			
		||||
            fieldValue: e.fieldValue?.toString()
 | 
			
		||||
          })),
 | 
			
		||||
          avatarUrl, openId, nickName, userType, unionId, corpName,
 | 
			
		||||
          totalScore: this.score,
 | 
			
		||||
          questionnaireTemplateId: this.$route.query.id
 | 
			
		||||
        }).then(res => {
 | 
			
		||||
          if (res?.code == 0) {
 | 
			
		||||
            this.result = {
 | 
			
		||||
              tips: "提交成功!感谢参与",
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
          this.$u.toast(err || "提交失败")
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    handleScore() {
 | 
			
		||||
      this.score = 0
 | 
			
		||||
      this.isExam && this.fields.map(field => {
 | 
			
		||||
        let item = field?.fieldInfo || {}
 | 
			
		||||
        let current = 0
 | 
			
		||||
        const calcScore = point => (current += (Number(point) || 0))
 | 
			
		||||
        if (item?.pointType == 0) {//此题有唯一答案和分值
 | 
			
		||||
          field.fieldValue?.toString() == item.answer?.toString() && calcScore(item?.points)
 | 
			
		||||
        } else if (item?.pointType == 1) {//每个选项都有对应分值
 | 
			
		||||
          item?.options?.map(op => {
 | 
			
		||||
            if (typeof field.fieldValue == "object") {
 | 
			
		||||
              if (field.fieldValue?.includes(op.label)) {
 | 
			
		||||
                calcScore(op.point)
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              op.label == field.fieldValue && calcScore(op.point)
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
        } else if (item?.pointType == 2) {//答对几项得几分,答错不得分
 | 
			
		||||
          item?.options?.some(op => {
 | 
			
		||||
            if (typeof field.fieldValue == "object") {
 | 
			
		||||
              if (field.fieldValue?.includes(op.label)) {
 | 
			
		||||
                if (item.answer?.includes(op.label)) calcScore(op.point)
 | 
			
		||||
                else return current = 0
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              op.label == field.fieldValue && calcScore(op.point)
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
        this.score += current
 | 
			
		||||
        //打印每题打分
 | 
			
		||||
        if (!!field.fieldValue) {
 | 
			
		||||
          const typeResult = (reply, answer) => {
 | 
			
		||||
            console.log("题目:%s,回答:%s,得分:%s,总分:%s \n 答案:%s", field.fieldName,
 | 
			
		||||
                reply, current, this.score, answer)
 | 
			
		||||
          }
 | 
			
		||||
          typeResult(field.fieldValue?.toString(), item.answer?.toString())
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.isResult ? this.getResult() : this.getForm()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.formDetail {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
 | 
			
		||||
  .headPicture {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 320px;
 | 
			
		||||
 | 
			
		||||
    .img {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .title {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    flex-wrap: wrap;
 | 
			
		||||
    padding: 32px;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    font-size: 34px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    color: #333;
 | 
			
		||||
    line-height: 48px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .bottom {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    padding: 32px;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    z-index: 99;
 | 
			
		||||
 | 
			
		||||
    .bottomBtn {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      line-height: 96px;
 | 
			
		||||
      background: #287DE1;
 | 
			
		||||
      color: #fff;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      height: 96px;
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .tableExplain {
 | 
			
		||||
    font-size: 28px;
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
    color: #666;
 | 
			
		||||
    padding: 32px 24px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .u-form-item {
 | 
			
		||||
    .u-form-item--left {
 | 
			
		||||
      font-size: 30px;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      color: #333;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .u-form-item--right__content__slot > * {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .display {
 | 
			
		||||
      justify-content: space-between;
 | 
			
		||||
      min-height: 58px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .uni-radio-input, .uni-checkbox-input {
 | 
			
		||||
      height: 32px;
 | 
			
		||||
      width: 32px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .label {
 | 
			
		||||
      flex-shrink: 0;
 | 
			
		||||
 | 
			
		||||
      * + & {
 | 
			
		||||
        margin-left: 16px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .option {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      margin-right: 16px;
 | 
			
		||||
      margin-bottom: 16px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .content {
 | 
			
		||||
    padding: 64px 32px 200px;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .scorePane {
 | 
			
		||||
    width: calc(100% - 40px);
 | 
			
		||||
    padding: 0 32px;
 | 
			
		||||
    height: 124px;
 | 
			
		||||
    background: #E9F2FF;
 | 
			
		||||
    border-radius: 16px;
 | 
			
		||||
    font-size: 30px;
 | 
			
		||||
    font-weight: 500;
 | 
			
		||||
    color: #333333;
 | 
			
		||||
    margin-top: 48px;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
 | 
			
		||||
    .fill {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    em {
 | 
			
		||||
      font-size: 48px;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
      color: #2C72FE;
 | 
			
		||||
      font-style: normal;
 | 
			
		||||
      margin-right: 8px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										225
									
								
								src/apps/AppInterview/AppInterview.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								src/apps/AppInterview/AppInterview.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="AppInterview">
 | 
			
		||||
    <AiTopFixed>
 | 
			
		||||
      <div flex>
 | 
			
		||||
        <AiDate placeholder="日期选择" mode="range" @change="handleDateSearch"/>
 | 
			
		||||
        <u-search placeholder="请输入标题" :show-action="false" v-model="search.title" @search="current=1,getList()"/>
 | 
			
		||||
      </div>
 | 
			
		||||
    </AiTopFixed>
 | 
			
		||||
    <template v-if="list.length>0">
 | 
			
		||||
      <AiCard :ref="'aiCard' + index" v-for="(e,index) in list" :key="index" @click.native="goDetail(e.id,1)">
 | 
			
		||||
        <template #custom>
 | 
			
		||||
          <div flex>
 | 
			
		||||
            <b class="fill">{{ e.title }}</b>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div flex v-if="!!e.fileList" class="wrap" @click.stop>
 | 
			
		||||
            <AiImage v-for="(op,i) in e.fileList.slice(0,3)" :src="op.accessUrl" preview :key="i"/>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="bottom">{{ e.createTime }}</div>
 | 
			
		||||
        </template>
 | 
			
		||||
        <template #menu>
 | 
			
		||||
          <div class="menu" @tap.stop="goDetail(e.id,false,index)">编辑</div>
 | 
			
		||||
          <div class="menu" @tap.stop="handleDelete(e.id, index)">删除</div>
 | 
			
		||||
        </template>
 | 
			
		||||
      </AiCard>
 | 
			
		||||
      <u-loadmore :status="loadmore" color="#999" font-size="24"
 | 
			
		||||
                  margin-top="32" margin-bottom="80"/>
 | 
			
		||||
    </template>
 | 
			
		||||
    <div class="no-message" v-else>
 | 
			
		||||
      <image src="https://cdn.cunwuyun.cn/wxAdmin/img/message.png"/>
 | 
			
		||||
      <p>您还未添加过入户调查走访<br>点击<b>新增按钮</b>试试吧~</p>
 | 
			
		||||
    </div>
 | 
			
		||||
    <AiFixedBtn>
 | 
			
		||||
      <div class="addBtn iconfont iconfont-iconfangda" @tap="gotoAdd()"/>
 | 
			
		||||
    </AiFixedBtn>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import qs from "query-string"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "AppInterview",
 | 
			
		||||
  appName: "调查走访",
 | 
			
		||||
  inject: {
 | 
			
		||||
    root: {}
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      search: {title: ""},
 | 
			
		||||
      list: [],
 | 
			
		||||
      current: 1,
 | 
			
		||||
      pages: 0,
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    loadmore() {
 | 
			
		||||
      return this.pages <= this.current ? 'loading ' : 'nomore'
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    getList() {
 | 
			
		||||
      this.$http.post('/app/appinterview/list-xcx', null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          current: this.current,
 | 
			
		||||
          size: 10,
 | 
			
		||||
          ...this.search
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records
 | 
			
		||||
          this.pages = res.data.pages
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    goDetail(id, readonly, index) {
 | 
			
		||||
      let query = {id}
 | 
			
		||||
      readonly && (query.detail = 1)
 | 
			
		||||
      index > -1 && this.$refs[`aiCard${index}`][0].handleClose()
 | 
			
		||||
      uni.navigateTo({url: `./interviewDetail?${qs.stringify(query)}`})
 | 
			
		||||
    },
 | 
			
		||||
    gotoAdd() {
 | 
			
		||||
      uni.navigateTo({url: `./interviewDetail`})
 | 
			
		||||
    },
 | 
			
		||||
    handleDelete(ids, index) {
 | 
			
		||||
      this.$refs[`aiCard${index}`][0].handleClose()
 | 
			
		||||
      this.$confirm("是否要删除该调查走访").then(() => {
 | 
			
		||||
        this.$http.post("/app/appinterview/delete", null, {
 | 
			
		||||
          params: {ids}
 | 
			
		||||
        }).then(res => {
 | 
			
		||||
          if (res?.code == 0) {
 | 
			
		||||
            this.$u.toast("删除成功!")
 | 
			
		||||
            this.getList()
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleDateSearch(v) {
 | 
			
		||||
      this.search.startTime = v?.startDate
 | 
			
		||||
      this.search.endTime = v?.endDate || v?.startDate
 | 
			
		||||
      this.current = 1
 | 
			
		||||
      this.getList()
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  onShow() {
 | 
			
		||||
    document.title = "调查走访"
 | 
			
		||||
    this.current = 1;
 | 
			
		||||
    this.getList()
 | 
			
		||||
  },
 | 
			
		||||
  onReachBottom() {
 | 
			
		||||
    this.current++;
 | 
			
		||||
    this.getList()
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.AppInterview {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
 | 
			
		||||
  .no-message {
 | 
			
		||||
    margin-top: 140px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    color: #888;
 | 
			
		||||
    font-size: 30px;
 | 
			
		||||
 | 
			
		||||
    b {
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      color: $uni-color-primary;
 | 
			
		||||
      padding: 0 8px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    image {
 | 
			
		||||
      width: 320px;
 | 
			
		||||
      height: 240px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .AiCard {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    min-height: 160px;
 | 
			
		||||
    background: #FFFFFF;
 | 
			
		||||
    padding: 32px 32px 0;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    position: relative;
 | 
			
		||||
 | 
			
		||||
    b {
 | 
			
		||||
      display: block;
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      font-size: 30px;
 | 
			
		||||
      white-space: nowrap;
 | 
			
		||||
      overflow: hidden;
 | 
			
		||||
      text-overflow: ellipsis;
 | 
			
		||||
      color: #333;
 | 
			
		||||
      margin-right: 60px;
 | 
			
		||||
      margin-bottom: 20px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .iconfont-iconMore {
 | 
			
		||||
      color: #666;
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      right: 32px;
 | 
			
		||||
      top: 32px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .bottom {
 | 
			
		||||
      font-size: 24px;
 | 
			
		||||
      color: #999999;
 | 
			
		||||
      padding: 24px 0;
 | 
			
		||||
      border-bottom: 1px solid rgba(221, 221, 221, .4);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .AiImage {
 | 
			
		||||
      width: 30%;
 | 
			
		||||
      margin-bottom: 8px;
 | 
			
		||||
      margin-right: 8px;
 | 
			
		||||
 | 
			
		||||
      image {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 218px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .addBtn {
 | 
			
		||||
    width: 96px;
 | 
			
		||||
    height: 96px;
 | 
			
		||||
    flex-shrink: 0;
 | 
			
		||||
    background: $uni-color-primary;
 | 
			
		||||
    box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
 | 
			
		||||
    font-size: 48px;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    border-radius: 50%;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    display: flex;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .menu {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    line-height: 80px;
 | 
			
		||||
    width: 192px;
 | 
			
		||||
    height: 80px;
 | 
			
		||||
    font-size: 28px;
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
    color: #333333;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .u-search {
 | 
			
		||||
    margin-bottom: 0 !important;
 | 
			
		||||
    padding-left: 146px;
 | 
			
		||||
    box-shadow: none;
 | 
			
		||||
 | 
			
		||||
    .u-content {
 | 
			
		||||
      padding-left: 50px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										177
									
								
								src/apps/AppInterview/interviewDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								src/apps/AppInterview/interviewDetail.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="interviewDetail">
 | 
			
		||||
    <template v-if="isEdit">
 | 
			
		||||
      <u-form ref="interviewForm" label-position="top" :model="form">
 | 
			
		||||
        <u-form-item label="调查走访事项" prop="title" required>
 | 
			
		||||
          <u-input v-model="form.title" placeholder="请输入,最多30字" maxlength="30"/>
 | 
			
		||||
        </u-form-item>
 | 
			
		||||
        <u-form-item label="调查走访内容" prop="content">
 | 
			
		||||
          <AiTextarea v-model="form.content" placeholder="请输入,最多500字" :maxlength="500"/>
 | 
			
		||||
        </u-form-item>
 | 
			
		||||
        <u-form-item label="图片(最多9张)">
 | 
			
		||||
          <AiUploader multiple :limit="9" :def.sync="form.fileList" action="/admin/file/add2"/>
 | 
			
		||||
        </u-form-item>
 | 
			
		||||
      </u-form>
 | 
			
		||||
      <div bottom>
 | 
			
		||||
        <u-button type="primary" @tap="submitForm">保存</u-button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template v-else>
 | 
			
		||||
      <div class="headerPane">
 | 
			
		||||
        <b>{{ form.title }}</b>
 | 
			
		||||
        <div>记录时间:{{ form.createTime }}</div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="contentPane">
 | 
			
		||||
        <div v-html="form.content"/>
 | 
			
		||||
        <div flex class="wrap">
 | 
			
		||||
          <AiImage v-for="(op,i) in form.fileList" :src="op.accessUrl" preview :key="i"/>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <AiBack/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'interviewDetail',
 | 
			
		||||
  inject: {root: {}},
 | 
			
		||||
  computed: {
 | 
			
		||||
    isEdit() {
 | 
			
		||||
      return this.$route.query?.detail != 1
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      form: {
 | 
			
		||||
        fileList: []
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.searchDetail();
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    submitForm() {
 | 
			
		||||
      if (!this.form.title) {
 | 
			
		||||
        return this.$u.toast("请输入调查走访事项")
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$refs.interviewForm?.validate(v => {
 | 
			
		||||
        if (v) {
 | 
			
		||||
          this.$http.post(`/app/appinterview/add-xcx`, {
 | 
			
		||||
            ...this.form
 | 
			
		||||
          }).then(res => {
 | 
			
		||||
            if (res?.code == 0) {
 | 
			
		||||
              this.$u.toast("提交成功!")
 | 
			
		||||
              setTimeout(() => {
 | 
			
		||||
                uni.navigateBack({})
 | 
			
		||||
              }, 1000)
 | 
			
		||||
            }
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    searchDetail() {
 | 
			
		||||
      let {id} = this.$route.query
 | 
			
		||||
      id && this.$http.post(`/app/appinterview/queryDetailById`, null, {
 | 
			
		||||
        params: {id}
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res?.data) {
 | 
			
		||||
          this.form = {...res.data};
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.interviewDetail {
 | 
			
		||||
  background: #F3F6F9;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
 | 
			
		||||
  .u-form {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
    background-color: #f3f6f9;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    padding: 0 0 188px;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    font-size: 30px;
 | 
			
		||||
 | 
			
		||||
    ::v-deep textarea {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ::v-deep .u-form-item {
 | 
			
		||||
      margin-bottom: 16px;
 | 
			
		||||
 | 
			
		||||
      .u-form-item--left__content__label {
 | 
			
		||||
        font-weight: 400;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      div[flex] {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  div[bottom] {
 | 
			
		||||
    z-index: 99;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    height: 112px;
 | 
			
		||||
 | 
			
		||||
    .u-btn {
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      border-radius: 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .headerPane {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    background: #3975C6;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    padding: 24px 32px 32px;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    font-size: 28px;
 | 
			
		||||
 | 
			
		||||
    b {
 | 
			
		||||
      display: block;
 | 
			
		||||
      font-size: 40px;
 | 
			
		||||
      line-height: 64px;
 | 
			
		||||
      letter-spacing: 2px;
 | 
			
		||||
      margin-bottom: 16px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .contentPane {
 | 
			
		||||
    padding: 32px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    font-size: 32px;
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
    color: #666;
 | 
			
		||||
    line-height: 56px;
 | 
			
		||||
 | 
			
		||||
    .wrap {
 | 
			
		||||
      margin-top: 32px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .AiImage {
 | 
			
		||||
      width: 31%;
 | 
			
		||||
      margin-bottom: 16px;
 | 
			
		||||
      margin-right: 16px;
 | 
			
		||||
 | 
			
		||||
      image {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 218px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										271
									
								
								src/apps/AppMeetingNotice/AppMeetingNotice.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								src/apps/AppMeetingNotice/AppMeetingNotice.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,271 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="meeting">
 | 
			
		||||
    <AiTopFixed>
 | 
			
		||||
      <u-grid :col="3" :border="false">
 | 
			
		||||
        <u-grid-item v-for="(item,index) in grid" :key="index" :custom-style="{padding:'14px 0'}"
 | 
			
		||||
                     @click="handleClick(index)">
 | 
			
		||||
          <u-icon :name="item.icon" :size="64"></u-icon>
 | 
			
		||||
          <view class="label">{{ item.label }}</view>
 | 
			
		||||
        </u-grid-item>
 | 
			
		||||
      </u-grid>
 | 
			
		||||
    </AiTopFixed>
 | 
			
		||||
    <div class="body">
 | 
			
		||||
      <header>待参加的会议</header>
 | 
			
		||||
      <template v-if="meetingList.length">
 | 
			
		||||
        <div class="card" v-for="(item,index) in meetingList" :key="index" @click="handleDetail(item)">
 | 
			
		||||
          <header>{{ item.title }}</header>
 | 
			
		||||
          <u-row justify="between">
 | 
			
		||||
            <div class="time">
 | 
			
		||||
              <span>{{ item.startTime|format }}</span>
 | 
			
		||||
              <span>{{ item.startTime|formatDate(0) }}年{{
 | 
			
		||||
                  item.startTime|formatDate(1)
 | 
			
		||||
                }}月{{ item.startTime|formatDate(2) }}日 周{{ item.startTime|formatWeek }}</span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="arrow"></div>
 | 
			
		||||
            <div class="time">
 | 
			
		||||
              <span>{{ item.endTime|format }}</span>
 | 
			
		||||
              <span>{{ item.endTime|formatDate(0) }}年{{ item.endTime|formatDate(1) }}月{{
 | 
			
		||||
                  item.endTime|formatDate(2)
 | 
			
		||||
                }}日 周{{ item.endTime|formatWeek }}</span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <u-row class="info">
 | 
			
		||||
            <span>发起人员:</span>
 | 
			
		||||
            <span v-text="item.userName"/>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <u-gap height="20"></u-gap>
 | 
			
		||||
          <u-row class="info" style="align-items: start;flex-wrap: nowrap;">
 | 
			
		||||
            <span style="flex-shrink: 0">会议地点:</span>
 | 
			
		||||
            <span>{{ item.address }}</span>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <div class="tag" :style="{background:'url(' + $cdn + tag(item.joinStatus) + ')'}"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </template>
 | 
			
		||||
      <template v-else>
 | 
			
		||||
        <AiEmpty/>
 | 
			
		||||
      </template>
 | 
			
		||||
    </div>
 | 
			
		||||
    <u-divider bg-color="#F5F5F5" v-if="meetingList.length">已经到底啦</u-divider>
 | 
			
		||||
    <AiAdd @add="add"/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import addMeeting from './addMeeting';
 | 
			
		||||
import belongToMe from './belongToMe';
 | 
			
		||||
import detail from './detail';
 | 
			
		||||
import meetingList from './meetingList';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "AppMeetingNotice",
 | 
			
		||||
  appName: "会议通知",
 | 
			
		||||
  components: {addMeeting, belongToMe, detail, meetingList},
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      meetingList: [],
 | 
			
		||||
      isList: true,
 | 
			
		||||
      comp: "",
 | 
			
		||||
      params: null,
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    grid() {
 | 
			
		||||
      return [
 | 
			
		||||
        {
 | 
			
		||||
          icon: this.$cdn + "/common/iconlshy.png",
 | 
			
		||||
          label: "历史会议"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          icon: this.$cdn + "/common/iconwfqd.png",
 | 
			
		||||
          label: "我发起的"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          icon: this.$cdn + "/common/iconcgx.png",
 | 
			
		||||
          label: "草稿箱"
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    tag(status) {
 | 
			
		||||
      return {
 | 
			
		||||
        "0": "common/1wqr.png",
 | 
			
		||||
        "1": "common/1yqr.png",
 | 
			
		||||
        "2": "common/1yqj.png",
 | 
			
		||||
        "3": "common/toDo.png",
 | 
			
		||||
      }[status]
 | 
			
		||||
    },
 | 
			
		||||
    handleDetail({id}) {
 | 
			
		||||
      uni.navigateTo({
 | 
			
		||||
        url: "/apps/AppMeetingNotice/detail?id=" + id
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    getData() {
 | 
			
		||||
      this.$http.post("/app/appmeetinginfo/list", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          listType: "1",
 | 
			
		||||
          meetingStatus: "1|2",
 | 
			
		||||
          size: 999
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          this.meetingList = res.data.records
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleClick(index) {
 | 
			
		||||
      let url
 | 
			
		||||
      if (index == 0 || index == 2) {
 | 
			
		||||
        url = "/apps/AppMeetingNotice/meetingList?index=" + index
 | 
			
		||||
      } else if (index == 1) {
 | 
			
		||||
        url = "/apps/AppMeetingNotice/belongToMe"
 | 
			
		||||
      }
 | 
			
		||||
      uni.navigateTo({url})
 | 
			
		||||
    },
 | 
			
		||||
    add() {
 | 
			
		||||
      uni.navigateTo({
 | 
			
		||||
        url: "/apps/AppMeetingNotice/addMeeting"
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onShow() {
 | 
			
		||||
    document.title = "会议通知";
 | 
			
		||||
    this.$dict.load("meetingNoticeBefore", "meetingNoticeAfter");
 | 
			
		||||
    this.getData();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  filters: {
 | 
			
		||||
    format(date) {
 | 
			
		||||
      return date.split(" ")[1].substr(0, 5)
 | 
			
		||||
    },
 | 
			
		||||
    formatDate(date, index) {
 | 
			
		||||
      return date.split(" ")[0].split("-")[index]
 | 
			
		||||
    },
 | 
			
		||||
    formatWeek(date) {
 | 
			
		||||
      return "日一二三四五六".charAt((new Date(date.split(" ")[0]).getDay()))
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.meeting {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background: #F5F5F5;
 | 
			
		||||
  padding-bottom: 48px;
 | 
			
		||||
 | 
			
		||||
  .label {
 | 
			
		||||
    font-size: 28px;
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
    color: #333333;
 | 
			
		||||
    line-height: 48px;
 | 
			
		||||
    margin-top: 8px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .body {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    padding: 40px 32px;
 | 
			
		||||
 | 
			
		||||
    & > header {
 | 
			
		||||
      font-size: 36px;
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      margin-bottom: 38px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .card {
 | 
			
		||||
      background-color: #FFFFFF;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 32px;
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
      margin-bottom: 32px;
 | 
			
		||||
      position: relative;
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        margin-bottom: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > header {
 | 
			
		||||
        width: 95%;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        font-weight: 600;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .time {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        margin: 46px 0;
 | 
			
		||||
 | 
			
		||||
        & > span:first-child {
 | 
			
		||||
          font-size: 60px;
 | 
			
		||||
          font-weight: 600;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
          line-height: 84px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > span:last-child {
 | 
			
		||||
          font-size: 22px;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .arrow {
 | 
			
		||||
        width: 28px;
 | 
			
		||||
        height: 68px;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
        position: relative;
 | 
			
		||||
        transform: rotate(180deg);
 | 
			
		||||
 | 
			
		||||
        &:before, &:after {
 | 
			
		||||
          content: "";
 | 
			
		||||
          width: 50px;
 | 
			
		||||
          height: 50px;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:before {
 | 
			
		||||
          top: 59px;
 | 
			
		||||
          background-color: #CCCCCC;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:after {
 | 
			
		||||
          left: 7px;
 | 
			
		||||
          top: 59px;
 | 
			
		||||
          background-color: #FFFFFF;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .info {
 | 
			
		||||
        & > span:first-child {
 | 
			
		||||
          font-size: 30px;
 | 
			
		||||
          color: #999999;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > span:last-child {
 | 
			
		||||
          font-size: 30px;
 | 
			
		||||
          color: #343D65;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .tag {
 | 
			
		||||
        width: 112px;
 | 
			
		||||
        height: 112px;
 | 
			
		||||
        background-repeat: no-repeat !important;
 | 
			
		||||
        background-size: 100% 100% !important;
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        top: 0;
 | 
			
		||||
        right: 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::v-deep .content {
 | 
			
		||||
    padding: 0 !important;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										428
									
								
								src/apps/AppMeetingNotice/addMeeting.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										428
									
								
								src/apps/AppMeetingNotice/addMeeting.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,428 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="add-meeting">
 | 
			
		||||
    <div v-if="!userSelect">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <header><em>*</em>会议标题</header>
 | 
			
		||||
        <input v-model="form.title" placeholder="请输入" :maxlength="30">
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <header><em>*</em>起止时间</header>
 | 
			
		||||
        <u-row justify="between">
 | 
			
		||||
          <div class="time" @click="pick(0)">
 | 
			
		||||
            <span>{{ form.startTime.time }}</span>
 | 
			
		||||
            <span>{{ form.startTime.year }}年{{ form.startTime.month }}月{{
 | 
			
		||||
                form.startTime.day
 | 
			
		||||
              }}日 周{{ form.startTime.weekday }}</span>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="arrow"></div>
 | 
			
		||||
          <div class="time" @click="pick(1)">
 | 
			
		||||
            <span>{{ form.endTime.time }}</span>
 | 
			
		||||
            <span>{{ form.endTime.year }}年{{ form.endTime.month }}月{{ form.endTime.day }}日 周{{
 | 
			
		||||
                form.endTime.weekday
 | 
			
		||||
              }}</span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </u-row>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <header><em>*</em>会议地点</header>
 | 
			
		||||
        <input v-model="form.address" placeholder="请输入" :maxlength="30">
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <header>会议内容</header>
 | 
			
		||||
        <textarea v-model="form.content" placeholder="请输入" :maxlength="500"></textarea>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <AiUploader :multiple="true" type="file" :limit="9" placeholder="上传附件" @list="fileList"
 | 
			
		||||
                    :def="form.files" action="/admin/file/add2"></AiUploader>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="card item-wrap">
 | 
			
		||||
        <u-row justify="between" class="item" @click="handleSelectUser">
 | 
			
		||||
          <header><em>*</em>参会人</header>
 | 
			
		||||
          <div class="right">
 | 
			
		||||
            <template v-if="!form.attendees.length">
 | 
			
		||||
              <span>请选择</span>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-else>
 | 
			
		||||
              已选择<em>{{ form.attendees.map(e => e.name).slice(0, 2).join("、") }}</em>等<em>{{
 | 
			
		||||
                form.attendees.length
 | 
			
		||||
              }}</em>人
 | 
			
		||||
            </template>
 | 
			
		||||
            <div class="right-arrow"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </u-row>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="card item-wrap" style="margin-top: 0">
 | 
			
		||||
        <u-row justify="between" class="item">
 | 
			
		||||
          <header>参会提醒</header>
 | 
			
		||||
          <picker class="right" @change="beforeNoticeChange" :value="form.noticeBefore" range-key="dictName"
 | 
			
		||||
                  :range="$dict.getDict('meetingNoticeBefore')">
 | 
			
		||||
            <span>{{
 | 
			
		||||
                form.noticeBefore != null ? $dict.getDict('meetingNoticeBefore')[form.noticeBefore]["dictName"] : "请选择"
 | 
			
		||||
              }}</span>
 | 
			
		||||
            <div class="right-arrow"></div>
 | 
			
		||||
          </picker>
 | 
			
		||||
        </u-row>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="card item-wrap" style="margin-top: 0">
 | 
			
		||||
        <u-row justify="between" class="item">
 | 
			
		||||
          <header>确认提醒</header>
 | 
			
		||||
          <picker class="right" @change="afterNoticeChange" :value="form.noticeAfter" range-key="dictName"
 | 
			
		||||
                  :range="$dict.getDict('meetingNoticeAfter')">
 | 
			
		||||
            <span>{{
 | 
			
		||||
                form.noticeAfter != null ? $dict.getDict('meetingNoticeAfter')[form.noticeAfter]["dictName"] : "请选择"
 | 
			
		||||
              }}</span>
 | 
			
		||||
            <div class="right-arrow"></div>
 | 
			
		||||
          </picker>
 | 
			
		||||
        </u-row>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="footer">
 | 
			
		||||
        <div @click="add(0)">保存草稿</div>
 | 
			
		||||
        <div @click="add(1)">发布会议</div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <u-picker mode="time" v-model="show" :params="options" @confirm="confirm"></u-picker>
 | 
			
		||||
    <AiBack ref="aiBack" v-if="!userSelect"/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "addMeeting",
 | 
			
		||||
  props: {
 | 
			
		||||
    params: {
 | 
			
		||||
      type: [Number, String]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    const initTime = {
 | 
			
		||||
      time: "",
 | 
			
		||||
      year: "",
 | 
			
		||||
      month: "",
 | 
			
		||||
      day: "",
 | 
			
		||||
      weekday: "",
 | 
			
		||||
      timestamp: "",
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      show: false,
 | 
			
		||||
      index: 0,
 | 
			
		||||
      list: [],
 | 
			
		||||
      form: {
 | 
			
		||||
        id: null,
 | 
			
		||||
        title: "",
 | 
			
		||||
        startTime: {...initTime},
 | 
			
		||||
        endTime: {...initTime},
 | 
			
		||||
        address: "",
 | 
			
		||||
        content: "",
 | 
			
		||||
        attendees: [],
 | 
			
		||||
        noticeBefore: 4,
 | 
			
		||||
        noticeAfter: 0,
 | 
			
		||||
        files: [],
 | 
			
		||||
      },
 | 
			
		||||
      userSelect: false,
 | 
			
		||||
      clickedUserSelect: false
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onLoad(opt) {
 | 
			
		||||
    if (opt.id) {
 | 
			
		||||
      this.form.id = opt.id
 | 
			
		||||
      this.getDetail()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.$nextTick(() => {
 | 
			
		||||
      let date = new Date();
 | 
			
		||||
      this.form.startTime.time = date.getHours()?.toString()?.padStart(2, "0") + ":" + date.getMinutes()?.toString()?.padStart(2, "0")
 | 
			
		||||
      this.form.startTime.year = date.getFullYear()
 | 
			
		||||
      this.form.startTime.month = (date.getMonth() + 1)?.toString()?.padStart(2, "0")
 | 
			
		||||
      this.form.startTime.day = date.getDate()
 | 
			
		||||
      this.form.startTime.weekday = '日一二三四五六'.charAt(date.getDay())
 | 
			
		||||
      this.form.endTime = {...this.form.startTime}
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onShow() {
 | 
			
		||||
    document.title = "新增会议";
 | 
			
		||||
    this.$dict.load("meetingNoticeBefore", "meetingNoticeAfter");
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  computed: {
 | 
			
		||||
    options() {
 | 
			
		||||
      return {
 | 
			
		||||
        year: true,
 | 
			
		||||
        month: true,
 | 
			
		||||
        day: true,
 | 
			
		||||
        hour: true,
 | 
			
		||||
        minute: true,
 | 
			
		||||
        timestamp: true,
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['selectEnterpriseContact']),
 | 
			
		||||
    handleSelectUser() {
 | 
			
		||||
      if (this.clickedUserSelect) return this.$u.toast("正在打开人员选择器")
 | 
			
		||||
      this.clickedUserSelect = true
 | 
			
		||||
      this.selectEnterpriseContact({
 | 
			
		||||
        fromDepartmentId: 0,
 | 
			
		||||
        type: ["user"],
 | 
			
		||||
        selectedUserIds: this.form.attendees?.map(e => e.id)
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        this.change(res?.userList || [])
 | 
			
		||||
        this.clickedUserSelect = false
 | 
			
		||||
      }).catch(() => {
 | 
			
		||||
        this.clickedUserSelect = false
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    fileList(e) {
 | 
			
		||||
      this.form.files = e
 | 
			
		||||
    },
 | 
			
		||||
    change(e) {
 | 
			
		||||
      this.form.attendees = e
 | 
			
		||||
    },
 | 
			
		||||
    beforeNoticeChange(e) {
 | 
			
		||||
      this.form.noticeBefore = e.detail.value
 | 
			
		||||
    },
 | 
			
		||||
    afterNoticeChange(e) {
 | 
			
		||||
      this.form.noticeAfter = e.detail.value
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getDetail() {
 | 
			
		||||
      this.$http.post("/app/appmeetinginfo/info-id", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          id: this.form.id
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          this.form.title = res.data.title
 | 
			
		||||
          this.form.address = res.data.address
 | 
			
		||||
          this.form.content = res.data.content
 | 
			
		||||
          this.form.attendees = res.data.attendees
 | 
			
		||||
          this.form.noticeBefore = res.data.noticeBefore
 | 
			
		||||
          this.form.noticeAfter = res.data.noticeAfter
 | 
			
		||||
          this.form.files = res.data.files
 | 
			
		||||
          this.form.startTime.time = res.data.startTime.split(" ")[1].substr(0, 5)
 | 
			
		||||
          this.form.startTime.year = res.data.startTime.split(" ")[0].split("-")[0]
 | 
			
		||||
          this.form.startTime.month = res.data.startTime.split(" ")[0].split("-")[1]
 | 
			
		||||
          this.form.startTime.day = res.data.startTime.split(" ")[0].split("-")[2]
 | 
			
		||||
          this.form.startTime.weekday = '日一二三四五六'.charAt(new Date(res.data.startTime.split(" ")[0]).getDay())
 | 
			
		||||
          this.form.startTime.timestamp = new Date(res.data.startTime).getTime()
 | 
			
		||||
 | 
			
		||||
          this.form.endTime.time = res.data.endTime.split(" ")[1].substr(0, 5)
 | 
			
		||||
          this.form.endTime.year = res.data.endTime.split(" ")[0].split("-")[0]
 | 
			
		||||
          this.form.endTime.month = res.data.endTime.split(" ")[0].split("-")[1]
 | 
			
		||||
          this.form.endTime.day = res.data.endTime.split(" ")[0].split("-")[2]
 | 
			
		||||
          this.form.endTime.weekday = '日一二三四五六'.charAt(new Date(res.data.endTime.split(" ")[0]).getDay())
 | 
			
		||||
          this.form.endTime.timestamp = new Date(res.data.endTime).getTime()
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    confirm(e) {
 | 
			
		||||
      if (new Date().getTime() / 1000 > e.timestamp) return this.$u.toast("选择时间不能小于当前时间")
 | 
			
		||||
      if (this.index == 0) {
 | 
			
		||||
        this.form.startTime = {...e}
 | 
			
		||||
        this.form.startTime.time = e.hour + ":" + (e.minute.length > 1 ? e.minute : ("0" + e.minute))
 | 
			
		||||
        this.form.startTime.weekday = '日一二三四五六'.charAt(new Date(e.timestamp * 1000).getDay())
 | 
			
		||||
      } else {
 | 
			
		||||
        if (this.form.startTime.timestamp >= e.timestamp) {
 | 
			
		||||
          return this.$u.toast("结束时间不能小于开始时间");
 | 
			
		||||
        }
 | 
			
		||||
        this.form.endTime = {...e}
 | 
			
		||||
        this.form.endTime.time = e.hour + ":" + (e.minute.length > 1 ? e.minute : ("0" + e.minute))
 | 
			
		||||
        this.form.endTime.weekday = '日一二三四五六'.charAt(new Date(e.timestamp * 1000).getDay())
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    add(status) {
 | 
			
		||||
      if (status == 1) {
 | 
			
		||||
        if (!this.form.title) return this.$u.toast("请输入会议标题")
 | 
			
		||||
 | 
			
		||||
        if (this.form.startTime.timestamp >= this.form.endTime.timestamp) return this.$u.toast("结束时间不能小于开始时间")
 | 
			
		||||
 | 
			
		||||
        if (!this.form.address) return this.$u.toast("请输入会议地点")
 | 
			
		||||
 | 
			
		||||
        // if (!this.form.content) return this.$u.toast("请输入会议内容")
 | 
			
		||||
 | 
			
		||||
        if (!this.form.attendees.length) return this.$u.toast("请选择参会人")
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$http.post("/app/appmeetinginfo/add-update", {
 | 
			
		||||
        ...this.form,
 | 
			
		||||
        files: this.form.files.map(e => e.id),
 | 
			
		||||
        status,
 | 
			
		||||
        startTime: this.form.startTime.year + "-" + this.form.startTime.month + "-" + this.form.startTime.day + " " + this.form.startTime.time + ":00",
 | 
			
		||||
        endTime: this.form.endTime.year + "-" + this.form.endTime.month + "-" + this.form.endTime.day + " " + this.form.endTime.time + ":00",
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.$u.toast(status == 1 ? "发布成功" : "保存成功")
 | 
			
		||||
          this.$refs["aiBack"].back()
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    pick(index) {
 | 
			
		||||
      this.index = index
 | 
			
		||||
      this.show = true
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.add-meeting {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background: #F5F5F5;
 | 
			
		||||
  padding-bottom: 140px;
 | 
			
		||||
 | 
			
		||||
  .card {
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    padding: 32px;
 | 
			
		||||
    margin-top: 16px;
 | 
			
		||||
 | 
			
		||||
    header {
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      font-weight: 400;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
 | 
			
		||||
      em {
 | 
			
		||||
        font-style: normal;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        color: #FF4466;
 | 
			
		||||
        margin-right: 8px;
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    input {
 | 
			
		||||
      margin: 32px 0 16px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    textarea {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      height: 160px;
 | 
			
		||||
      margin: 32px 0 16px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .u-row {
 | 
			
		||||
      margin-top: 34px;
 | 
			
		||||
 | 
			
		||||
      .time {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
 | 
			
		||||
        & > span:first-child {
 | 
			
		||||
          font-size: 60px;
 | 
			
		||||
          font-weight: 600;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
          line-height: 84px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > span:last-child {
 | 
			
		||||
          font-size: 22px;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .arrow {
 | 
			
		||||
        width: 28px;
 | 
			
		||||
        height: 68px;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
        position: relative;
 | 
			
		||||
        transform: rotate(180deg);
 | 
			
		||||
 | 
			
		||||
        &:before, &:after {
 | 
			
		||||
          content: "";
 | 
			
		||||
          width: 50px;
 | 
			
		||||
          height: 50px;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:before {
 | 
			
		||||
          top: 59px;
 | 
			
		||||
          background-color: #CCCCCC;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:after {
 | 
			
		||||
          left: 7px;
 | 
			
		||||
          top: 59px;
 | 
			
		||||
          background-color: #FFFFFF;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .item {
 | 
			
		||||
      height: 112px;
 | 
			
		||||
      box-shadow: 0px -1px 0px 0px #D8DDE6;
 | 
			
		||||
      margin-top: 0;
 | 
			
		||||
 | 
			
		||||
      .right {
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        color: #999999;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
 | 
			
		||||
        em {
 | 
			
		||||
          font-style: normal;
 | 
			
		||||
          color: #1365DD;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .right-arrow {
 | 
			
		||||
        width: 16px;
 | 
			
		||||
        height: 16px;
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
        border-top: 5px solid #CCCCCC;
 | 
			
		||||
        border-right: 5px solid #CCCCCC;
 | 
			
		||||
        transform: rotate(45deg);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .item-wrap {
 | 
			
		||||
    padding: 0 32px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .footer {
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
 | 
			
		||||
    & > div {
 | 
			
		||||
      font-size: 36px;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > div:first-child {
 | 
			
		||||
      width: 270px;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > div:last-child {
 | 
			
		||||
      width: calc(100% - 270px);
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      color: #FFFFFF;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      background-color: #1365DD;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										238
									
								
								src/apps/AppMeetingNotice/belongToMe.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								src/apps/AppMeetingNotice/belongToMe.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="belong-to-me">
 | 
			
		||||
    <AiTopFixed>
 | 
			
		||||
      <u-tabs :list="tabs" :is-scroll="false" :current="index" bar-width="88" :height="96" @change="change"></u-tabs>
 | 
			
		||||
    </AiTopFixed>
 | 
			
		||||
    <div class="body">
 | 
			
		||||
      <template v-if="list.length">
 | 
			
		||||
        <div class="card" v-for="(item,index) in list" :key="index" @click="handleClick(item)">
 | 
			
		||||
          <header>{{ item.title }}</header>
 | 
			
		||||
          <u-row justify="between">
 | 
			
		||||
            <div class="time">
 | 
			
		||||
              <span>{{ item.startTime|formatTime }}</span>
 | 
			
		||||
              <span>{{ item.startTime|formatDate(0) }}年{{
 | 
			
		||||
                  item.startTime|formatDate(1)
 | 
			
		||||
                }}月{{ item.startTime|formatDate(2) }}日 周{{ item.startTime|formatWeek }}</span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="arrow"></div>
 | 
			
		||||
            <div class="time">
 | 
			
		||||
              <span>{{ item.endTime|formatTime }}</span>
 | 
			
		||||
              <span>{{ item.endTime|formatDate(0) }}年{{ item.endTime|formatDate(1) }}月{{ item.endTime|formatDate(2) }}日 周{{
 | 
			
		||||
                  item.endTime|formatWeek
 | 
			
		||||
                }}</span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <u-row class="info">
 | 
			
		||||
            <span>发起单位:</span>
 | 
			
		||||
            <span v-text="item.unitName"/>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <u-gap height="20"></u-gap>
 | 
			
		||||
          <u-row class="info">
 | 
			
		||||
            <span>会议地点:</span>
 | 
			
		||||
            <span>{{ item.address }}</span>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <div class="tag" :style="{background:'url(' + tag(item.status) + ')'}"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </template>
 | 
			
		||||
      <template v-else>
 | 
			
		||||
        <AiEmpty/>
 | 
			
		||||
      </template>
 | 
			
		||||
    </div>
 | 
			
		||||
    <AiBack/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "belongToMe",
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      index: 0,
 | 
			
		||||
      current: 1,
 | 
			
		||||
      list: [],
 | 
			
		||||
      status: "加载更多",
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    tabs() {
 | 
			
		||||
      return [
 | 
			
		||||
        {name: "全部"},
 | 
			
		||||
        {name: "未开始"},
 | 
			
		||||
        {name: "进行中"},
 | 
			
		||||
        {name: "已取消"},
 | 
			
		||||
        {name: "已结束"},
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  onShow() {
 | 
			
		||||
    document.title = "我发起的";
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.injectJWeixin(['sendChatMessage']).then(() => {
 | 
			
		||||
      this.getList()
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  onReachBottom() {
 | 
			
		||||
    this.current++;
 | 
			
		||||
    this.getList()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['injectJWeixin']),
 | 
			
		||||
    tag(status) {
 | 
			
		||||
      return {
 | 
			
		||||
        "1": this.$cdn + 'common/1wks.png',
 | 
			
		||||
        "2": this.$cdn + 'common/1jxz.png',
 | 
			
		||||
        "3": this.$cdn + 'common/1yqx.png',
 | 
			
		||||
        "4": this.$cdn + 'common/1yjs.png'
 | 
			
		||||
      }[status]
 | 
			
		||||
    },
 | 
			
		||||
    getList() {
 | 
			
		||||
      this.$http.post("/app/appmeetinginfo/list", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          listType: 0,
 | 
			
		||||
          meetingStatus: this.index == 0 ? "-1" : this.index,
 | 
			
		||||
          size: 10,
 | 
			
		||||
          current: this.current
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          if (this.current > 1 && this.current > res.data.pages) {
 | 
			
		||||
            this.status = "已经到底啦"
 | 
			
		||||
          }
 | 
			
		||||
          this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleClick({id}) {
 | 
			
		||||
      uni.navigateTo({
 | 
			
		||||
        url: "/apps/AppMeetingNotice/detail?id=" + id
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    change(e) {
 | 
			
		||||
      this.index = e
 | 
			
		||||
      this.current = 1
 | 
			
		||||
      this.getList()
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  filters: {
 | 
			
		||||
    formatTime(date) {
 | 
			
		||||
      return date.split(" ")[1]?.substr(0, 5)
 | 
			
		||||
    },
 | 
			
		||||
    formatDate(date, i) {
 | 
			
		||||
      return date.split(" ")[0]?.split("-")[i]
 | 
			
		||||
    },
 | 
			
		||||
    formatWeek(date) {
 | 
			
		||||
      return "日一二三四五六".charAt(new Date(date.split(" ")[0]).getDay())
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.belong-to-me {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background-color: #F5F5F5;
 | 
			
		||||
 | 
			
		||||
  ::v-deep .content {
 | 
			
		||||
    padding: 0 !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .body {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    padding: 40px 32px;
 | 
			
		||||
 | 
			
		||||
    .card {
 | 
			
		||||
      background-color: #FFFFFF;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 32px;
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
      margin-bottom: 32px;
 | 
			
		||||
      position: relative;
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        margin-bottom: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > header {
 | 
			
		||||
        width: 95%;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        font-weight: 600;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .time {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        margin: 46px 0;
 | 
			
		||||
 | 
			
		||||
        & > span:first-child {
 | 
			
		||||
          font-size: 60px;
 | 
			
		||||
          font-weight: 600;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
          line-height: 84px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > span:last-child {
 | 
			
		||||
          font-size: 22px;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .arrow {
 | 
			
		||||
        width: 28px;
 | 
			
		||||
        height: 68px;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
        position: relative;
 | 
			
		||||
        transform: rotate(180deg);
 | 
			
		||||
 | 
			
		||||
        &:before, &:after {
 | 
			
		||||
          content: "";
 | 
			
		||||
          width: 50px;
 | 
			
		||||
          height: 50px;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:before {
 | 
			
		||||
          top: 59px;
 | 
			
		||||
          background-color: #CCCCCC;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:after {
 | 
			
		||||
          left: 7px;
 | 
			
		||||
          top: 59px;
 | 
			
		||||
          background-color: #FFFFFF;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .info {
 | 
			
		||||
        flex-wrap: nowrap;
 | 
			
		||||
 | 
			
		||||
        & > span:first-child {
 | 
			
		||||
          font-size: 30px;
 | 
			
		||||
          color: #999999;
 | 
			
		||||
          flex-shrink: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > span:last-child {
 | 
			
		||||
          font-size: 30px;
 | 
			
		||||
          color: #343D65;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .tag {
 | 
			
		||||
        width: 112px;
 | 
			
		||||
        height: 112px;
 | 
			
		||||
        background-repeat: no-repeat;
 | 
			
		||||
        background-size: 100% 100% !important;
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        top: 0;
 | 
			
		||||
        right: 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										561
									
								
								src/apps/AppMeetingNotice/detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										561
									
								
								src/apps/AppMeetingNotice/detail.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,561 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="detail" v-if="pageShow">
 | 
			
		||||
    <template v-if="!list">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <header>{{ detail.title }}</header>
 | 
			
		||||
        <u-gap height="16"></u-gap>
 | 
			
		||||
        <u-row v-if="detail.createUserId">
 | 
			
		||||
          <!--          <u-avatar :src="$cdn + 'common/xzh.png'" v-if="false"></u-avatar>-->
 | 
			
		||||
          <div class="u-avatar__img">
 | 
			
		||||
            {{detail.userName}}
 | 
			
		||||
          </div>
 | 
			
		||||
          <span class="user-name">
 | 
			
		||||
             {{detail.userName}}
 | 
			
		||||
          </span>
 | 
			
		||||
        </u-row>
 | 
			
		||||
        <u-gap height="32"></u-gap>
 | 
			
		||||
        <u-row>
 | 
			
		||||
          <img :src="$cdn + 'common/meeting.png'" alt="">
 | 
			
		||||
          <span :style="{color:color(detail.status)}">{{ $dict.getLabel('meetStatus', detail.status) }}</span>
 | 
			
		||||
        </u-row>
 | 
			
		||||
        <u-gap height="8"></u-gap>
 | 
			
		||||
        <u-row>
 | 
			
		||||
          <img :src="$cdn + 'common/date.png'" alt="">
 | 
			
		||||
          <span>{{
 | 
			
		||||
              detail.startTime && detail.startTime.substr(0, 16)
 | 
			
		||||
            }} 至 {{ detail.endTime && detail.endTime.substr(0, 16) }}</span>
 | 
			
		||||
        </u-row>
 | 
			
		||||
        <u-gap height="8"></u-gap>
 | 
			
		||||
        <u-row style="align-items: start;flex-wrap: nowrap;">
 | 
			
		||||
          <img :src="$cdn + 'common/location.png'" alt="">
 | 
			
		||||
          <span>{{ detail.address }}</span>
 | 
			
		||||
        </u-row>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <span>{{ detail.content }}</span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="card" v-if="detail.files && detail.files.length">
 | 
			
		||||
        <div class="label">相关附件</div>
 | 
			
		||||
        <div class="file" v-for="(item,index) in detail.files" @click="preFile(item)" :key="index">
 | 
			
		||||
          <u-row justify="between">
 | 
			
		||||
            <label class="left">
 | 
			
		||||
              <img :src="$cdn + 'common/appendix.png'" alt="">
 | 
			
		||||
              <span>{{ item.fileName }}.{{ item.postfix }}</span>
 | 
			
		||||
            </label>
 | 
			
		||||
            <span>{{ item.fileSizeStr }}</span>
 | 
			
		||||
          </u-row>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="card item-wrap">
 | 
			
		||||
        <u-row justify="between">
 | 
			
		||||
          <span>参会人</span>
 | 
			
		||||
          <label class="right" @click="list=true">
 | 
			
		||||
            查看全部<em>{{ detail.attendees && detail.attendees.length }}</em>人
 | 
			
		||||
            <div class="right-arrow"/>
 | 
			
		||||
          </label>
 | 
			
		||||
        </u-row>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="footer cancel" v-if="detail.status==1 && detail.createUserId == user.id" @click="handleCancel">取消会议
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <template v-else>
 | 
			
		||||
        <div class="footer" v-if="['1','2'].includes(detail.status) && ['0','3'].includes(detail.joinStatus)">
 | 
			
		||||
          <div class="leave" @click="updateStatus(0)">
 | 
			
		||||
            <img :src="$cdn + 'sass/leave.png'" alt="">请假
 | 
			
		||||
          </div>
 | 
			
		||||
          <div @click="toDo" class="leave">
 | 
			
		||||
            <img :src="$cdn + 'sass/toBe.png'" alt="">待定
 | 
			
		||||
          </div>
 | 
			
		||||
          <div @click="updateStatus(1)">确认会议</div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <!--        <div class="footer" v-if="['1','2'].includes(detail.status) && detail.joinStatus!=0">-->
 | 
			
		||||
        <!--          <label>{{ detail.joinStatus|transform }}</label>-->
 | 
			
		||||
        <!--          <img :src="$cdn + tag(detail.joinStatus)" alt="">-->
 | 
			
		||||
        <!--        </div>-->
 | 
			
		||||
      </template>
 | 
			
		||||
 | 
			
		||||
    </template>
 | 
			
		||||
    <template v-else>
 | 
			
		||||
      <div class="att-list">
 | 
			
		||||
        <AiTopFixed>
 | 
			
		||||
          <u-tabs :list="tabs" :current="current" height="96" :is-scroll="false" bar-width="192"
 | 
			
		||||
                  @change="change"></u-tabs>
 | 
			
		||||
        </AiTopFixed>
 | 
			
		||||
        <div v-for="(item,index) in detail.attendees && detail.attendees.filter(e=>e.joinStatus==current)" :key="index"
 | 
			
		||||
             class="att-wrap">
 | 
			
		||||
          <div class="left">
 | 
			
		||||
            <u-avatar :src="item.avatar || (($cdn + 'common/xztx.png'))" size="74" mode="square"
 | 
			
		||||
                      style="margin-right: 8px"></u-avatar>
 | 
			
		||||
            <span v-text="item.name"/>
 | 
			
		||||
          </div>
 | 
			
		||||
          <!--          <img :src="$cdn + 'common/phone.png'" alt="" @click="call(item)">-->
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <u-modal v-model="show" title="提示" show-cancel-button content='是否要取消该会议?' @confirm="onConfirm"></u-modal>
 | 
			
		||||
    <AiBack/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions, mapState} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "detail",
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      detail: {},
 | 
			
		||||
      list: false,
 | 
			
		||||
      current: 0,
 | 
			
		||||
      pageShow: false,
 | 
			
		||||
      show: false,
 | 
			
		||||
      id: null,
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  onLoad(opt) {
 | 
			
		||||
    this.id = opt.id;
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    ...mapState(["user"]),
 | 
			
		||||
    tabs() {
 | 
			
		||||
      return [
 | 
			
		||||
        {name: this.count(0) + "人未确认"},
 | 
			
		||||
        {name: this.count(1) + "人已确认"},
 | 
			
		||||
        {name: this.count(2) + "人已请假"},
 | 
			
		||||
        {name: this.count(3) + "人待定"},
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    onConfirm() {
 | 
			
		||||
      this.$http.post("/app/appmeetinginfo/cancel", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          meetingId: this.id,
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.$u.toast("取消成功");
 | 
			
		||||
          this.getDetail();
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleCancel() {
 | 
			
		||||
      this.show = true;
 | 
			
		||||
    },
 | 
			
		||||
    toDo() {
 | 
			
		||||
      this.$http.post("/app/appmeetinginfo/tobeConfirm", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          meetingId: this.id,
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.$u.toast("会议待定");
 | 
			
		||||
          setTimeout(_ => {
 | 
			
		||||
            uni.navigateBack();
 | 
			
		||||
          }, 800)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    count(sta) {
 | 
			
		||||
      return this.detail.attendees ? this.detail.attendees?.filter(e => e.joinStatus == sta)?.length : 0;
 | 
			
		||||
    },
 | 
			
		||||
    change(index) {
 | 
			
		||||
      this.current = index;
 | 
			
		||||
      this.detail = {};
 | 
			
		||||
      this.getDetail();
 | 
			
		||||
    },
 | 
			
		||||
    call(item) {
 | 
			
		||||
      if (item.phone) {
 | 
			
		||||
        uni.makePhoneCall({
 | 
			
		||||
          phoneNumber: item.phone
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    ...mapActions(['previewFile', 'injectJWeixin']),
 | 
			
		||||
    preFile(e) {
 | 
			
		||||
      if ([".jpg", ".png", ".gif"].includes(e.postfix.toLowerCase())) {
 | 
			
		||||
        uni.previewImage({
 | 
			
		||||
          current: e.url,
 | 
			
		||||
          urls: [e.url]
 | 
			
		||||
        })
 | 
			
		||||
      } else {
 | 
			
		||||
        this.previewFile({...e})
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    tag(status) {
 | 
			
		||||
      return {
 | 
			
		||||
        "1": "common/2confirmed2.png",
 | 
			
		||||
        "2": "common/2absent2.png"
 | 
			
		||||
      }[status]
 | 
			
		||||
    },
 | 
			
		||||
    updateStatus(status) {
 | 
			
		||||
      this.$http.post(status == 0 ? "/app/appmeetinginfo/absent" : "/app/appmeetinginfo/confirm", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          meetingId: this.id,
 | 
			
		||||
          reason: status == 0 ? "" : null
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.$u.toast(status == 0 ? "请假成功" : "确认成功")
 | 
			
		||||
          this.getDetail()
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    color(status) {
 | 
			
		||||
      if (status == 1) {
 | 
			
		||||
        return "#FF8822"
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (status == 2) {
 | 
			
		||||
        return "#1365DD"
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (status == 3) {
 | 
			
		||||
        return "#FF4466"
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return "#343D65"
 | 
			
		||||
    },
 | 
			
		||||
    getDetail() {
 | 
			
		||||
      this.$http.post("/app/appmeetinginfo/info-id", null, {
 | 
			
		||||
        params: {id: this.id}
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          this.detail = res.data
 | 
			
		||||
          this.pageShow = true
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.injectJWeixin(['sendChatMessage']).then(() => {
 | 
			
		||||
      this.getDetail()
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onShow() {
 | 
			
		||||
    document.title = "会议详情";
 | 
			
		||||
    this.$dict.load("meetStatus");
 | 
			
		||||
    wx.hideOptionMenu();
 | 
			
		||||
  },
 | 
			
		||||
  filters: {
 | 
			
		||||
    transform(status) {
 | 
			
		||||
      if (status == 1) {
 | 
			
		||||
        return "已确认"
 | 
			
		||||
      }
 | 
			
		||||
      if (status == 2) {
 | 
			
		||||
        return "已请假"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.detail {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background-color: #F5F5F5;
 | 
			
		||||
  padding-bottom: 140px;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  ::v-deep .AiTopFixed {
 | 
			
		||||
    margin-bottom: 16px;
 | 
			
		||||
 | 
			
		||||
    .content {
 | 
			
		||||
      padding: 0 !important;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  .att-list {
 | 
			
		||||
    min-height: 100%;
 | 
			
		||||
 | 
			
		||||
    .att-wrap {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      height: 112px;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: space-between;
 | 
			
		||||
      background-color: #ffffff;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 50px;
 | 
			
		||||
      border-bottom: 1px solid #E4E5E6;
 | 
			
		||||
 | 
			
		||||
      .left {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
 | 
			
		||||
        &:after {
 | 
			
		||||
          content: "";
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          right: 0;
 | 
			
		||||
          bottom: 0;
 | 
			
		||||
          width: 622px;
 | 
			
		||||
          height: 2px;
 | 
			
		||||
          background-color: rgba(216, 221, 230, 0.5);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .name {
 | 
			
		||||
          font-size: 30px;
 | 
			
		||||
          font-weight: 600;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > img {
 | 
			
		||||
        width: 48px;
 | 
			
		||||
        height: 48px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .card {
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    margin-bottom: 8px;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    padding: 16px 32px;
 | 
			
		||||
 | 
			
		||||
    header {
 | 
			
		||||
      font-size: 40px;
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      line-height: 64px;
 | 
			
		||||
      letter-spacing: 1px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .u-row {
 | 
			
		||||
      & > div {
 | 
			
		||||
        border-radius: 50%;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        /*margin-left: 8px;*/
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > span {
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        color: #343D65;
 | 
			
		||||
        margin-left: 16px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      ::v-deep .u-avatar__img {
 | 
			
		||||
        width: 56px;
 | 
			
		||||
        height: 56px;
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
        color: #ffffff;
 | 
			
		||||
        background-color: #2266FF;
 | 
			
		||||
        font-size: 16px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .user-name {
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        color: #343D65;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      img {
 | 
			
		||||
        width: 48px;
 | 
			
		||||
        height: 48px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > span {
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      line-height: 48px;
 | 
			
		||||
      letter-spacing: 1px;
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 16px 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .label {
 | 
			
		||||
      height: 96px;
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      margin-bottom: 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .file {
 | 
			
		||||
      height: 128px;
 | 
			
		||||
      background: #FFFFFF;
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
      border: 1px solid #CCCCCC;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
      margin-bottom: 32px;
 | 
			
		||||
 | 
			
		||||
      & > .u-row {
 | 
			
		||||
        height: 100%;
 | 
			
		||||
 | 
			
		||||
        .left {
 | 
			
		||||
          width: 522px;
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
 | 
			
		||||
          & > img {
 | 
			
		||||
            width: 96px;
 | 
			
		||||
            height: 96px;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          & > span {
 | 
			
		||||
            font-size: 32px;
 | 
			
		||||
            color: #333333;
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            line-height: 44px;
 | 
			
		||||
            text-overflow: ellipsis;
 | 
			
		||||
            overflow-x: hidden;
 | 
			
		||||
            white-space: nowrap;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > span {
 | 
			
		||||
          font-size: 28px;
 | 
			
		||||
          color: #999999;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .active {
 | 
			
		||||
      background-color: #F3F6F9;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .name {
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      font-weight: 400;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .wrap {
 | 
			
		||||
      height: 112px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      position: relative;
 | 
			
		||||
 | 
			
		||||
      &:after {
 | 
			
		||||
        content: "";
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        right: 0;
 | 
			
		||||
        bottom: 0;
 | 
			
		||||
        width: 622px;
 | 
			
		||||
        height: 2px;
 | 
			
		||||
        background-color: rgba(216, 221, 230, 0.5);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > label {
 | 
			
		||||
        width: 80px;
 | 
			
		||||
        height: 80px;
 | 
			
		||||
        border-radius: 50%;
 | 
			
		||||
        background-color: #4E8EEE;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        font-weight: 600;
 | 
			
		||||
        color: #FFFFFF;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .item-wrap {
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    padding: 0 32px;
 | 
			
		||||
 | 
			
		||||
    .u-row {
 | 
			
		||||
      height: 100%;
 | 
			
		||||
 | 
			
		||||
      & > span {
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        font-weight: 400;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .right {
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
      color: #999999;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
 | 
			
		||||
      em {
 | 
			
		||||
        font-style: normal;
 | 
			
		||||
        color: #1365DD;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .right-arrow {
 | 
			
		||||
        width: 16px;
 | 
			
		||||
        height: 16px;
 | 
			
		||||
        border-top: 5px solid #CCCCCC;
 | 
			
		||||
        border-right: 5px solid #CCCCCC;
 | 
			
		||||
        transform: rotate(45deg);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .footer {
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
 | 
			
		||||
    & > div {
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
      color: #666666;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
 | 
			
		||||
      & > img {
 | 
			
		||||
        width: 48px;
 | 
			
		||||
        height: 48px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > div:nth-child(1), & > div:nth-child(2) {
 | 
			
		||||
      width: 135px;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > div:last-child {
 | 
			
		||||
      width: calc(100% - 270px);
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      color: #FFFFFF;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      background-color: #1365DD;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > label {
 | 
			
		||||
      font-size: 36px;
 | 
			
		||||
      font-weight: 400;
 | 
			
		||||
      color: #999999;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*img {*/
 | 
			
		||||
    /*  width: 158px;*/
 | 
			
		||||
    /*  height: 104px;*/
 | 
			
		||||
    /*  position: absolute;*/
 | 
			
		||||
    /*  right: 0;*/
 | 
			
		||||
    /*  top: 0;*/
 | 
			
		||||
    /*}*/
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .cancel {
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    font-size: 36px;
 | 
			
		||||
    background-color: #005DFF
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										226
									
								
								src/apps/AppMeetingNotice/meetingList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								src/apps/AppMeetingNotice/meetingList.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,226 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="meeting-list">
 | 
			
		||||
    <div class="card" v-for="(item,index) in list" :key="index" @click="detail(item)">
 | 
			
		||||
      <header>
 | 
			
		||||
        <span>{{ item.title }}</span>
 | 
			
		||||
        <span>
 | 
			
		||||
          <span v-if="index==2">保存于</span>
 | 
			
		||||
          {{ item.createTime }}</span>
 | 
			
		||||
      </header>
 | 
			
		||||
      <u-row justify="between">
 | 
			
		||||
        <div class="time">
 | 
			
		||||
          <span>{{ item.startTime|format }}</span>
 | 
			
		||||
          <span>{{ item.startTime|formatDate(0) }}年{{ item.startTime|formatDate(1) }}月{{ item.startTime|formatDate(2) }}日 周{{ item.startTime|formatWeek }}</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="arrow"></div>
 | 
			
		||||
        <div class="time">
 | 
			
		||||
          <span>{{ item.endTime|format }}</span>
 | 
			
		||||
          <span>{{ item.endTime|formatDate(0) }}年{{ item.endTime|formatDate(1) }}月{{ item.endTime|formatDate(2) }}日 周{{ item.endTime|formatWeek }}</span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </u-row>
 | 
			
		||||
      <u-row class="info">
 | 
			
		||||
        <span>发起人员:</span>
 | 
			
		||||
        <span v-text="item.createUserName"/>
 | 
			
		||||
      </u-row>
 | 
			
		||||
      <u-gap height="20"></u-gap>
 | 
			
		||||
      <u-row class="info">
 | 
			
		||||
        <span>会议地点:</span>
 | 
			
		||||
        <span>{{ item.address }}</span>
 | 
			
		||||
      </u-row>
 | 
			
		||||
      <div class="tag" v-if="item.status!=0" :style="{background:'url(' + $cdn + tag(item.status) +')'}"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <u-loadmore :status="status" v-if="list.length"/>
 | 
			
		||||
    <AiEmpty v-if="!list.length"></AiEmpty>
 | 
			
		||||
    <AiBack/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "meetingList",
 | 
			
		||||
  props: {
 | 
			
		||||
    params: {
 | 
			
		||||
      type: [String, Number, Object],
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      list: [],
 | 
			
		||||
      current: 1,
 | 
			
		||||
      index: null,
 | 
			
		||||
      status: "加载更多",
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onLoad(opt) {
 | 
			
		||||
    this.index = opt.index
 | 
			
		||||
    uni.setNavigationBarTitle({
 | 
			
		||||
      title: opt.index == 0 ? "历史会议" : "草稿箱"
 | 
			
		||||
    });
 | 
			
		||||
    this.getData();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    detail({id}) {
 | 
			
		||||
      let url
 | 
			
		||||
      if (this.index == 2) {
 | 
			
		||||
        url = "/apps/AppMeetingNotice/addMeeting?id=" + id
 | 
			
		||||
      } else {
 | 
			
		||||
        url = "/apps/AppMeetingNotice/detail?id=" + id
 | 
			
		||||
      }
 | 
			
		||||
      uni.navigateTo({url})
 | 
			
		||||
    },
 | 
			
		||||
    tag(status) {
 | 
			
		||||
      return {
 | 
			
		||||
        "1": 'common/1wks.png',
 | 
			
		||||
        "2": 'common/1jxz.png',
 | 
			
		||||
        "3": 'common/1yqx.png',
 | 
			
		||||
        "4": 'common/1yjs.png'
 | 
			
		||||
      }[status]
 | 
			
		||||
    },
 | 
			
		||||
    getData() {
 | 
			
		||||
      this.$http.post("/app/appmeetinginfo/list", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          listType: this.index == 0 ? "2" : '0',
 | 
			
		||||
          meetingStatus: this.index == 0 ? "4" : "0",
 | 
			
		||||
          size: 10,
 | 
			
		||||
          current: this.current,
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          if (this.current > 1 && this.current > res.data.pages) {
 | 
			
		||||
            this.status = "已经到底啦"
 | 
			
		||||
          }
 | 
			
		||||
          this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onReachBottom() {
 | 
			
		||||
    this.current++;
 | 
			
		||||
    this.getData();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  filters: {
 | 
			
		||||
    format(date) {
 | 
			
		||||
      return date.split(" ")[1].substr(0, 5)
 | 
			
		||||
    },
 | 
			
		||||
    formatDate(date, index) {
 | 
			
		||||
      return date.split(" ")[0].split("-")[index]
 | 
			
		||||
    },
 | 
			
		||||
    formatWeek(date) {
 | 
			
		||||
      return "日一二三四五六".charAt((new Date(date.split(" ")[0]).getDay()))
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.meeting-list {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background-color: #F5F5F5;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  padding: 32px;
 | 
			
		||||
 | 
			
		||||
  .card {
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    padding: 32px;
 | 
			
		||||
    border-radius: 8px;
 | 
			
		||||
    margin-bottom: 32px;
 | 
			
		||||
    position: relative;
 | 
			
		||||
 | 
			
		||||
    &:last-child {
 | 
			
		||||
      margin-bottom: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > header {
 | 
			
		||||
      width: 95%;
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
 | 
			
		||||
      & > span:last-child {
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        font-weight: 400;
 | 
			
		||||
        color: #999999;
 | 
			
		||||
        margin-top: 10px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .time {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      margin: 46px 0;
 | 
			
		||||
 | 
			
		||||
      & > span:first-child {
 | 
			
		||||
        font-size: 60px;
 | 
			
		||||
        font-weight: 600;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        line-height: 84px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > span:last-child {
 | 
			
		||||
        font-size: 22px;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .arrow {
 | 
			
		||||
      width: 28px;
 | 
			
		||||
      height: 68px;
 | 
			
		||||
      overflow: hidden;
 | 
			
		||||
      position: relative;
 | 
			
		||||
      transform: rotate(180deg);
 | 
			
		||||
 | 
			
		||||
      &:before, &:after {
 | 
			
		||||
        content: "";
 | 
			
		||||
        width: 50px;
 | 
			
		||||
        height: 50px;
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:before {
 | 
			
		||||
        top: 59px;
 | 
			
		||||
        background-color: #CCCCCC;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      &:after {
 | 
			
		||||
        left: 7px;
 | 
			
		||||
        top: 59px;
 | 
			
		||||
        background-color: #FFFFFF;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .info {
 | 
			
		||||
      flex-wrap: nowrap;
 | 
			
		||||
 | 
			
		||||
      & > span:first-child {
 | 
			
		||||
        flex-shrink: 0;
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        color: #999999;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > span:last-child {
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        color: #343D65;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .tag {
 | 
			
		||||
      width: 112px;
 | 
			
		||||
      height: 112px;
 | 
			
		||||
      background-repeat: no-repeat !important;
 | 
			
		||||
      background-size: 100% 100% !important;
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      top: 0;
 | 
			
		||||
      right: 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										379
									
								
								src/apps/AppNotification/AppNotification.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								src/apps/AppNotification/AppNotification.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,379 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="notification">
 | 
			
		||||
    <template v-if="showList">
 | 
			
		||||
      <AiTopFixed>
 | 
			
		||||
        <u-tabs :list="tabs" :is-scroll="false" height="96" :current="index" bar-width="192" @change="change"></u-tabs>
 | 
			
		||||
      </AiTopFixed>
 | 
			
		||||
      <div class="body" v-if="dataList.length">
 | 
			
		||||
        <div class="card" v-for="(item,idx) in dataList" :key="idx" @click="handeClick(item)">
 | 
			
		||||
          <template v-if="!item.imgUrl">
 | 
			
		||||
            <label>
 | 
			
		||||
              <span class="status" v-if="index==0 && item.readStatus==0">未读</span>
 | 
			
		||||
              <span class="status read" v-if="index==0 && item.readStatus!=0">已读</span>
 | 
			
		||||
              <div class="tag" v-if="index==1" :style="color(item.status)">
 | 
			
		||||
                {{ $dict.getLabel("announcementStatus", item.status) }}
 | 
			
		||||
              </div>
 | 
			
		||||
              {{ item.title }}
 | 
			
		||||
            </label>
 | 
			
		||||
            <u-gap height="16"></u-gap>
 | 
			
		||||
            <span class="info">
 | 
			
		||||
              <text>{{ item.releaseUserName }}</text>
 | 
			
		||||
            <text>{{ item.releaseTime }}</text>
 | 
			
		||||
          </span>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template v-else>
 | 
			
		||||
            <div class="has-pic">
 | 
			
		||||
              <div class="left">
 | 
			
		||||
                <label>
 | 
			
		||||
                  <span class="status" v-if="index==0 && item.readStatus==0">未读</span>
 | 
			
		||||
                  <span class="status read" v-if="index==0 && item.readStatus!=0">已读</span>
 | 
			
		||||
                  <div class="tag" v-if="index==1" :style="color(item.status)">
 | 
			
		||||
                    {{ $dict.getLabel("announcementStatus", item.status) }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  {{ item.title }}
 | 
			
		||||
                </label>
 | 
			
		||||
                <u-gap height="16"></u-gap>
 | 
			
		||||
                <span class="info">
 | 
			
		||||
                <text>{{ item.releaseUserName }}</text>
 | 
			
		||||
                <text>{{ item.releaseTime }}</text>
 | 
			
		||||
              </span>
 | 
			
		||||
              </div>
 | 
			
		||||
              <img :src="item.imgUrl" alt="">
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <AiEmpty v-else/>
 | 
			
		||||
      <u-loadmore :status="status" v-if="dataList.length"/>
 | 
			
		||||
      <AiAdd @add="handleAdd"/>
 | 
			
		||||
      <u-popup v-model="show" mode="bottom">
 | 
			
		||||
        <div class="popup-wrap">
 | 
			
		||||
          <u-row justify="between">
 | 
			
		||||
            <div class="colum" v-for="(item,index) in optList" :key="index" @click="handleOpt(item)">
 | 
			
		||||
              <u-icon :name="item.icon" size="100" :custom-style="{backgroundColor:'#fff',borderRadius:'8px'}"></u-icon>
 | 
			
		||||
              <u-gap height="16"></u-gap>
 | 
			
		||||
              {{ item.name }}
 | 
			
		||||
            </div>
 | 
			
		||||
          </u-row>
 | 
			
		||||
          <div class="btn" @click="show=false">关闭</div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </u-popup>
 | 
			
		||||
      <u-modal v-model="modal" :content="'是否确定' + content + '该公告?'" title="" show-confirm-button
 | 
			
		||||
               show-cancel-button confirm-text="确定" cancel-text="取消"
 | 
			
		||||
               @confirm="confirm" @cancel="modal=false"></u-modal>
 | 
			
		||||
    </template>
 | 
			
		||||
    <component :is="comp" v-else :params="params"></component>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import add from "./add";
 | 
			
		||||
import detail from "./detail";
 | 
			
		||||
import read from "./read";
 | 
			
		||||
import {mapActions} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "AppNotification",
 | 
			
		||||
  appName: "通知公告",
 | 
			
		||||
  components: {add, detail, read},
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      index: 0,
 | 
			
		||||
      show: false,
 | 
			
		||||
      modal: false,
 | 
			
		||||
      content: "",
 | 
			
		||||
      current: 1,
 | 
			
		||||
      dataList: [],
 | 
			
		||||
      detail: {},
 | 
			
		||||
      showList: true,
 | 
			
		||||
      comp: "",
 | 
			
		||||
      params: null,
 | 
			
		||||
      status: "加载更多",
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  computed: {
 | 
			
		||||
    tabs() {
 | 
			
		||||
      return [{name: "最新公告"}, {name: "公告管理"}];
 | 
			
		||||
    },
 | 
			
		||||
    optList() {
 | 
			
		||||
      return [
 | 
			
		||||
        {
 | 
			
		||||
          name: "详情",
 | 
			
		||||
          icon: this.$cdn + "notice/yl.png",
 | 
			
		||||
          val: 0,
 | 
			
		||||
          show: true,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: "撤回",
 | 
			
		||||
          icon: this.$cdn + "notice/ch.png",
 | 
			
		||||
          val: 1,
 | 
			
		||||
          show: this.detail?.status == 1,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: "发布",
 | 
			
		||||
          icon: this.$cdn + "notice/fb.png",
 | 
			
		||||
          val: 2,
 | 
			
		||||
          show: this.detail?.status == 0,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: "编辑",
 | 
			
		||||
          icon: this.$cdn + "notice/bj.png",
 | 
			
		||||
          val: 3,
 | 
			
		||||
          show: this.detail?.status == 0 || this.detail?.status == 3,
 | 
			
		||||
        }, {
 | 
			
		||||
          name: "删除",
 | 
			
		||||
          icon: this.$cdn + "notice/sc.png",
 | 
			
		||||
          val: 4,
 | 
			
		||||
          show: true,
 | 
			
		||||
        }
 | 
			
		||||
      ].filter(e => e.show)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onShow() {
 | 
			
		||||
    this.current = 1;
 | 
			
		||||
    document.title = "通知公告";
 | 
			
		||||
    this.$dict.load("announcementStatus");
 | 
			
		||||
    this.injectJWeixin(['sendChatMessage']).then(() => {
 | 
			
		||||
      this.getList();
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onReachBottom() {
 | 
			
		||||
    this.current++;
 | 
			
		||||
    this.getList();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['injectJWeixin']),
 | 
			
		||||
    changeState() {
 | 
			
		||||
      this.$http.post(this.content == '删除' ? '/app/appannouncement/delete' : "/app/appannouncement/update-status", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          [this.content == '删除' ? 'ids' : 'id']: this.detail.id
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.$u.toast(this.content + "成功");
 | 
			
		||||
          this.modal = false;
 | 
			
		||||
          this.getList();
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    confirm() {
 | 
			
		||||
      this.show = false;
 | 
			
		||||
      this.changeState();
 | 
			
		||||
    },
 | 
			
		||||
    handleOpt(item) {
 | 
			
		||||
      this.content = {
 | 
			
		||||
        1: "撤回",
 | 
			
		||||
        2: "发布",
 | 
			
		||||
        4: "删除",
 | 
			
		||||
      }[item.val];
 | 
			
		||||
 | 
			
		||||
      if (item.val == 0) {
 | 
			
		||||
        this.show = false;
 | 
			
		||||
        return uni.navigateTo({
 | 
			
		||||
          url: "/apps/AppNotification/detail?id=" + this.detail.id
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ([1, 2, 4].includes(item.val)) {
 | 
			
		||||
        return this.modal = true;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (item.val == 3) {
 | 
			
		||||
        this.show = false;
 | 
			
		||||
        return uni.navigateTo({
 | 
			
		||||
          url: "/apps/AppNotification/add?id=" + this.detail.id + "&flag=" + false
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    color(status) {
 | 
			
		||||
      return [
 | 
			
		||||
        {backgroundColor: "rgba(255,136,34,0.1)", color: "#FF8822"},
 | 
			
		||||
        {backgroundColor: "rgba(34,102,255,0.1)", color: "#2266FF"},
 | 
			
		||||
        {backgroundColor: "rgba(102,102,102,0.1)", color: "#666666"},
 | 
			
		||||
        {backgroundColor: "rgba(255,136,34,0.1)", color: "#FF8822"}
 | 
			
		||||
      ][status];
 | 
			
		||||
    },
 | 
			
		||||
    handeClick(item) {
 | 
			
		||||
      this.detail = item;
 | 
			
		||||
      if (this.index == 1) {
 | 
			
		||||
        this.show = true;
 | 
			
		||||
      } else {
 | 
			
		||||
        uni.navigateTo({
 | 
			
		||||
          url: "/apps/AppNotification/detail?id=" + this.detail.id + "&flag=" + true
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    handleAdd() {
 | 
			
		||||
      uni.navigateTo({
 | 
			
		||||
        url: "/apps/AppNotification/add"
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    change(val) {
 | 
			
		||||
      this.index = val;
 | 
			
		||||
      this.current = 1;
 | 
			
		||||
      this.dataList = [];
 | 
			
		||||
      this.getList();
 | 
			
		||||
    },
 | 
			
		||||
    getList() {
 | 
			
		||||
      this.$http.post(this.index == 0 ? "/app/appannouncement/list-latest" : "/app/appannouncement/list-mgr", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          size: 10,
 | 
			
		||||
          current: this.current
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          if (this.current > 1 && this.current > res.data.pages) {
 | 
			
		||||
            this.status = "已经到底啦"
 | 
			
		||||
          }
 | 
			
		||||
          this.dataList = this.current > 1 ? [...this.dataList, ...res.data.records] : res.data.records
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.notification {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background-color: #F5F5F5;
 | 
			
		||||
  padding-bottom: 32px;
 | 
			
		||||
 | 
			
		||||
  ::v-deep .content {
 | 
			
		||||
    padding: 0 !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .body {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    padding: 32px;
 | 
			
		||||
 | 
			
		||||
    .card {
 | 
			
		||||
      height: 255px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-direction: column;
 | 
			
		||||
      justify-content: space-between;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 32px;
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
      background-color: #ffffff;
 | 
			
		||||
      margin-bottom: 32px;
 | 
			
		||||
 | 
			
		||||
      &:last-child {
 | 
			
		||||
        margin-bottom: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > label {
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
        text-overflow: ellipsis;
 | 
			
		||||
        display: -webkit-box;
 | 
			
		||||
        -webkit-box-orient: vertical;
 | 
			
		||||
        -webkit-line-clamp: 2;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        line-height: 44px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .tag {
 | 
			
		||||
        width: 96px;
 | 
			
		||||
        height: 44px;
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
        border-radius: 8px;
 | 
			
		||||
        margin-right: 16px;
 | 
			
		||||
        font-size: 26px;
 | 
			
		||||
        font-weight: 400;
 | 
			
		||||
        line-height: 46px;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .info {
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        color: #999999;
 | 
			
		||||
        line-height: 40px;
 | 
			
		||||
 | 
			
		||||
        & > text:first-child {
 | 
			
		||||
          margin-right: 32px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > .has-pic {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: space-between;
 | 
			
		||||
 | 
			
		||||
        & > .left {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          flex-direction: column;
 | 
			
		||||
          justify-content: space-between;
 | 
			
		||||
 | 
			
		||||
          & > label {
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
            text-overflow: ellipsis;
 | 
			
		||||
            display: -webkit-box;
 | 
			
		||||
            -webkit-box-orient: vertical;
 | 
			
		||||
            -webkit-line-clamp: 2;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > img {
 | 
			
		||||
          width: 192px;
 | 
			
		||||
          height: 144px;
 | 
			
		||||
          flex-shrink: 0;
 | 
			
		||||
          margin-left: 32px;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .status {
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      width: 88px;
 | 
			
		||||
      height: 36px;
 | 
			
		||||
      font-size: 26px;
 | 
			
		||||
      color: #FF8822;
 | 
			
		||||
      background: rgba(255, 136, 34, .1);
 | 
			
		||||
      line-height: 36px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      margin-right: 4px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .read {
 | 
			
		||||
      background: rgba(102, 102, 102, .1);
 | 
			
		||||
      color: #666666;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .popup-wrap {
 | 
			
		||||
    height: 368px;
 | 
			
		||||
    background-color: #F7F7F7;
 | 
			
		||||
 | 
			
		||||
    .btn {
 | 
			
		||||
      height: 96px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      font-size: 30px;
 | 
			
		||||
      font-weight: 500;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      background-color: #ffffff;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > .u-row {
 | 
			
		||||
      height: 272px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 46px;
 | 
			
		||||
 | 
			
		||||
      & > .colum {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        font-size: 26px;
 | 
			
		||||
        color: #666666;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										367
									
								
								src/apps/AppNotification/add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								src/apps/AppNotification/add.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,367 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="add-meeting">
 | 
			
		||||
    <div v-if="!userSelect">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <header><em>*</em>公告标题</header>
 | 
			
		||||
        <input v-model="form.title" placeholder="请输入" :maxlength="30">
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <header><em>*</em>公告内容</header>
 | 
			
		||||
        <textarea v-model="form.content" placeholder="请输入" :maxlength="500"></textarea>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <AiUploader :multiple="true" type="image" :limit="9" placeholder="上传图片" @list="fileList" :def="form.files"
 | 
			
		||||
                    action="/admin/file/add2"></AiUploader>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="card item-wrap">
 | 
			
		||||
        <u-row justify="between" class="item" style="border-bottom: 1px solid #eeeeee" @click="handleSelectUser">
 | 
			
		||||
          <header><em>*</em>发送对象</header>
 | 
			
		||||
          <div class="right">
 | 
			
		||||
            <template v-if="!form.persons.length">
 | 
			
		||||
              <span>请选择</span>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-else>
 | 
			
		||||
              已选择<em>{{ form.persons.map(e => e.name).slice(0, 2).join("、") }}</em>等<em>{{ form.persons.length }}</em>人
 | 
			
		||||
            </template>
 | 
			
		||||
            <div class="right-arrow"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </u-row>
 | 
			
		||||
 | 
			
		||||
        <u-row justify="between" class="item" @click="userSelect=true">
 | 
			
		||||
          <header><em>*</em>发送时间</header>
 | 
			
		||||
        </u-row>
 | 
			
		||||
        <u-row justify="between">
 | 
			
		||||
          <div class="type" :class="[index==0 && 'active']" @click="index=0,form.releaseTime=null">立即发送
 | 
			
		||||
            <img :src="$cdn + 'notice/jiaobiao.png'" alt="" v-show="index==0">
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="type" :class="[index==1 && 'active']" @click="index=1">定时发送
 | 
			
		||||
            <img :src="$cdn + 'notice/jiaobiao.png'" alt="" v-show="index==1">
 | 
			
		||||
          </div>
 | 
			
		||||
        </u-row>
 | 
			
		||||
        <u-gap height="38"></u-gap>
 | 
			
		||||
        <u-row justify="between" class="item" style="box-shadow: none;" @click="show=true" v-show="index==1">
 | 
			
		||||
          <header><em>*</em>定时发送时间</header>
 | 
			
		||||
          <div class="right">
 | 
			
		||||
            <template v-if="!form.releaseTime">
 | 
			
		||||
              <span>请选择</span>
 | 
			
		||||
            </template>
 | 
			
		||||
            <template v-else>
 | 
			
		||||
              <span>{{ form.releaseTime }}</span>
 | 
			
		||||
            </template>
 | 
			
		||||
            <div class="right-arrow"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </u-row>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="footer">
 | 
			
		||||
        <div @click="add(0)">保存草稿</div>
 | 
			
		||||
        <div @click="add(1)">立即发布</div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <AiBack ref="aiBack" v-if="!userSelect"/>
 | 
			
		||||
    <u-picker v-model="show" mode="time" :params="options" @confirm="confirm"></u-picker>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "add",
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      show: false,
 | 
			
		||||
      index: 0,
 | 
			
		||||
      list: [],
 | 
			
		||||
      form: {
 | 
			
		||||
        id: null,
 | 
			
		||||
        title: "",
 | 
			
		||||
        content: "",
 | 
			
		||||
        persons: [],
 | 
			
		||||
        releaseTime: null,
 | 
			
		||||
        files: [],
 | 
			
		||||
      },
 | 
			
		||||
      userSelect: false,
 | 
			
		||||
      flag: null,
 | 
			
		||||
      options: {
 | 
			
		||||
        year: true,
 | 
			
		||||
        month: true,
 | 
			
		||||
        day: true,
 | 
			
		||||
        hour: true,
 | 
			
		||||
        minute: true,
 | 
			
		||||
        second: true,
 | 
			
		||||
        timestamp: true,
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onLoad(opt) {
 | 
			
		||||
    if (opt.id) {
 | 
			
		||||
      this.form.id = opt.id;
 | 
			
		||||
      this.flag = opt.flag;
 | 
			
		||||
      this.getDetail();
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['selectEnterpriseContact']),
 | 
			
		||||
    handleSelectUser() {
 | 
			
		||||
      this.selectEnterpriseContact({
 | 
			
		||||
        fromDepartmentId: 0,
 | 
			
		||||
        type: ["user"],
 | 
			
		||||
        selectedUserIds: this.form.persons?.map(e => e.id)
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        this.form.persons = res?.userList || []
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    confirm(e) {
 | 
			
		||||
      if (e.timestamp < (Date.now() / 1000) || 0) {
 | 
			
		||||
        return this.$u.toast("发送时间不能小于当前时间");
 | 
			
		||||
      }
 | 
			
		||||
      this.form.releaseTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}:${e.second}`;
 | 
			
		||||
    },
 | 
			
		||||
    fileList(e) {
 | 
			
		||||
      this.form.files = e
 | 
			
		||||
    },
 | 
			
		||||
    change(e) {
 | 
			
		||||
      this.form.persons = e
 | 
			
		||||
    },
 | 
			
		||||
    getDetail() {
 | 
			
		||||
      this.$http.post("/app/appannouncement/detail", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          id: this.form.id,
 | 
			
		||||
          detail: this.flag
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          this.form.releaseTime = res.data.releaseTime;
 | 
			
		||||
          Object.keys(this.form).map(e => {
 | 
			
		||||
            this.form[e] = res.data[e];
 | 
			
		||||
          })
 | 
			
		||||
          this.index = res.data.releaseTime ? 1 : 0;
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    add(status) {
 | 
			
		||||
      // if(status==1){
 | 
			
		||||
      if (!this.form.title) return this.$u.toast("请输入公告标题")
 | 
			
		||||
 | 
			
		||||
      if (!this.form.content) return this.$u.toast("请输入公告内容")
 | 
			
		||||
 | 
			
		||||
      if (!this.form.persons.length) return this.$u.toast("请选择发送对象")
 | 
			
		||||
 | 
			
		||||
      if (this.index == 1 && !this.form.releaseTime) return this.$u.toast("请选择定时发送时间")
 | 
			
		||||
 | 
			
		||||
      if (this.form.releaseTime && new Date(this.form.releaseTime).getTime() < Date.now()) return this.$u.toast("发送时间不能小于当前时间");
 | 
			
		||||
      // }
 | 
			
		||||
 | 
			
		||||
      this.$http.post("/app/appannouncement/addOrUpdate", {
 | 
			
		||||
        ...this.form,
 | 
			
		||||
        status,
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          this.$u.toast(status == 1 ? "发布成功" : "保存成功");
 | 
			
		||||
          uni.navigateBack({})
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onShow() {
 | 
			
		||||
    document.title = "新增公告";
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    background() {
 | 
			
		||||
      return `url(${this.$cdn}/notice/jiaobiao.png) no-repeat; background-size: 46px 48px;position: absolute;bottom: 0;right: 0;`
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.add-meeting {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background: #F5F5F5;
 | 
			
		||||
  padding-bottom: 140px;
 | 
			
		||||
 | 
			
		||||
  .card {
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    padding: 32px;
 | 
			
		||||
    margin-top: 16px;
 | 
			
		||||
 | 
			
		||||
    header {
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      font-weight: 400;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
 | 
			
		||||
      em {
 | 
			
		||||
        font-style: normal;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        color: #FF4466;
 | 
			
		||||
        margin-right: 8px;
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    input {
 | 
			
		||||
      margin: 32px 0 16px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    textarea {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      height: 160px;
 | 
			
		||||
      margin: 32px 0 16px;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .u-row {
 | 
			
		||||
      margin-top: 34px;
 | 
			
		||||
 | 
			
		||||
      .time {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
 | 
			
		||||
        & > span:first-child {
 | 
			
		||||
          font-size: 60px;
 | 
			
		||||
          font-weight: 600;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
          line-height: 84px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > span:last-child {
 | 
			
		||||
          font-size: 22px;
 | 
			
		||||
          color: #333333;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .arrow {
 | 
			
		||||
        width: 28px;
 | 
			
		||||
        height: 68px;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
        position: relative;
 | 
			
		||||
        transform: rotate(180deg);
 | 
			
		||||
 | 
			
		||||
        &:before, &:after {
 | 
			
		||||
          content: "";
 | 
			
		||||
          width: 50px;
 | 
			
		||||
          height: 50px;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          transform: scaleY(1.3) translate(30%, -40px) rotate(45deg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:before {
 | 
			
		||||
          top: 59px;
 | 
			
		||||
          background-color: #CCCCCC;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &:after {
 | 
			
		||||
          left: 7px;
 | 
			
		||||
          top: 59px;
 | 
			
		||||
          background-color: #FFFFFF;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .type {
 | 
			
		||||
        width: 320px;
 | 
			
		||||
        height: 112px;
 | 
			
		||||
        background: #F5F5F5;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        border-radius: 4px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        font-weight: 500;
 | 
			
		||||
        letter-spacing: 1px;
 | 
			
		||||
        position: relative;
 | 
			
		||||
 | 
			
		||||
        & > img {
 | 
			
		||||
          width: 46px;
 | 
			
		||||
          height: 48px;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          right: 0;
 | 
			
		||||
          bottom: 0;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .active {
 | 
			
		||||
        background-color: #E7F1FE;
 | 
			
		||||
        color: #1174FE;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .item {
 | 
			
		||||
      height: 112px;
 | 
			
		||||
      box-shadow: 0px -1px 0px 0px #D8DDE6;
 | 
			
		||||
      margin-top: 0;
 | 
			
		||||
 | 
			
		||||
      .right {
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        color: #999999;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
 | 
			
		||||
        em {
 | 
			
		||||
          font-style: normal;
 | 
			
		||||
          color: #1365DD;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .right-arrow {
 | 
			
		||||
        width: 16px;
 | 
			
		||||
        height: 16px;
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
        border-top: 5px solid #CCCCCC;
 | 
			
		||||
        border-right: 5px solid #CCCCCC;
 | 
			
		||||
        transform: rotate(45deg);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .item-wrap {
 | 
			
		||||
    padding: 0 32px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .footer {
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
 | 
			
		||||
    & > div {
 | 
			
		||||
      font-size: 36px;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > div:first-child {
 | 
			
		||||
      width: 270px;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > div:last-child {
 | 
			
		||||
      width: calc(100% - 270px);
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      color: #FFFFFF;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
      background-color: #1365DD;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										356
									
								
								src/apps/AppNotification/detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										356
									
								
								src/apps/AppNotification/detail.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,356 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="detail" v-if="pageShow">
 | 
			
		||||
    <template v-if="detailObj.status!=2">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <header>{{ detailObj.title }}</header>
 | 
			
		||||
        <u-gap height="16"></u-gap>
 | 
			
		||||
        <u-row>
 | 
			
		||||
          <span>发布人:</span>
 | 
			
		||||
          <span v-text="detailObj.releaseUserName"/>
 | 
			
		||||
        </u-row>
 | 
			
		||||
        <u-gap height="8"></u-gap>
 | 
			
		||||
        <u-row>
 | 
			
		||||
          <span>发布部门:</span>
 | 
			
		||||
          <span v-text="detailObj.unitName"/>
 | 
			
		||||
        </u-row>
 | 
			
		||||
        <u-gap height="8"></u-gap>
 | 
			
		||||
        <u-row>
 | 
			
		||||
          <span>发布日期:</span>
 | 
			
		||||
          <span>{{ detailObj.releaseTime }}</span>
 | 
			
		||||
        </u-row>
 | 
			
		||||
        <u-gap height="8"></u-gap>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <div class="label">公告内容</div>
 | 
			
		||||
        <u-parse :html="detailObj.content"></u-parse>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="card" style="padding-top: 0" v-if="detailObj.files && detailObj.files.length">
 | 
			
		||||
        <div class="label">相关附件</div>
 | 
			
		||||
        <div class="file" v-for="(item,index) in detailObj.files" :key="index" @click="preFile(item)">
 | 
			
		||||
          <u-row justify="between">
 | 
			
		||||
            <label class="left">
 | 
			
		||||
              <img :src="$cdn + 'common/appendix.png'" alt="">
 | 
			
		||||
              <span>{{ item.name }}.{{ item.postfix }}</span>
 | 
			
		||||
            </label>
 | 
			
		||||
            <span>{{ (item.size / 1024).toFixed(2) }}KB</span>
 | 
			
		||||
          </u-row>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="card" @click="handleClick">
 | 
			
		||||
        <u-row justify="between" class="item">
 | 
			
		||||
          <span>接收对象</span>
 | 
			
		||||
          <div class="right">
 | 
			
		||||
            <em>{{ detailObj.readNum }}人</em>已读
 | 
			
		||||
            <em>{{ detailObj.unReadNum }}人</em>未读
 | 
			
		||||
            <div class="arrow"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </u-row>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <AiEmpty description="该通知已撤回" v-else/>
 | 
			
		||||
    <AiBack/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "detail",
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      detailObj: {},
 | 
			
		||||
      id: null,
 | 
			
		||||
      pageShow: false,
 | 
			
		||||
      flag: false,
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onLoad(opt) {
 | 
			
		||||
    this.id = opt.id;
 | 
			
		||||
    this.flag = opt.flag;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  created() {
 | 
			
		||||
    this.injectJWeixin(['sendChatMessage']).then(() => {
 | 
			
		||||
      this.getDetail()
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onShow() {
 | 
			
		||||
    document.title = "公告详情";
 | 
			
		||||
    wx.hideOptionMenu();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['previewFile', 'injectJWeixin']),
 | 
			
		||||
    preFile(e) {
 | 
			
		||||
      if ([".jpg", ".png", ".gif"].includes(e.postfix.toLowerCase())) {
 | 
			
		||||
        uni.previewImage({
 | 
			
		||||
          current: e.url,
 | 
			
		||||
          urls: [e.url]
 | 
			
		||||
        })
 | 
			
		||||
      } else {
 | 
			
		||||
        this.previewFile({...e})
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    getDetail() {
 | 
			
		||||
      this.$http.post("/app/appannouncement/detail", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          id: this.id,
 | 
			
		||||
          detail: this.flag
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          this.detailObj = res.data;
 | 
			
		||||
          this.pageShow = true
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    handleClick() {
 | 
			
		||||
      uni.navigateTo({
 | 
			
		||||
        url: "/apps/AppNotification/read?id=" + this.id,
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.detail {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background-color: #F5F5F5;
 | 
			
		||||
  padding-bottom: 140px;
 | 
			
		||||
 | 
			
		||||
  ::v-deep .content {
 | 
			
		||||
    padding: 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .card {
 | 
			
		||||
    background-color: #FFFFFF;
 | 
			
		||||
    margin-bottom: 8px;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    padding: 16px 32px;
 | 
			
		||||
 | 
			
		||||
    header {
 | 
			
		||||
      font-size: 40px;
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      line-height: 64px;
 | 
			
		||||
      letter-spacing: 1px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .u-row {
 | 
			
		||||
      & > div {
 | 
			
		||||
        border-radius: 50%;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        font-size: 22px;
 | 
			
		||||
        font-weight: bold;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > span {
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        color: #343D65;
 | 
			
		||||
        line-height: 48px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > span:last-child {
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        /*color: #343D65;*/
 | 
			
		||||
        /*margin-left: 16px;*/
 | 
			
		||||
        line-height: 48px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .title {
 | 
			
		||||
        width: 490px;
 | 
			
		||||
        height: 112px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
        text-overflow: ellipsis;
 | 
			
		||||
        white-space: nowrap;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .right {
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        color: #666666;
 | 
			
		||||
 | 
			
		||||
        .arrow {
 | 
			
		||||
          width: 16px;
 | 
			
		||||
          height: 16px;
 | 
			
		||||
          border-top: 3px solid #CCCCCC;
 | 
			
		||||
          border-right: 3px solid #CCCCCC;
 | 
			
		||||
          transform: rotate(45deg);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .item {
 | 
			
		||||
      position: relative;
 | 
			
		||||
      height: 80px;
 | 
			
		||||
 | 
			
		||||
      &:after {
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        height: 1px;
 | 
			
		||||
        background-color: rgba(216, 221, 230, 0.5);
 | 
			
		||||
        content: "";
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        left: 0;
 | 
			
		||||
        bottom: 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > span {
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      line-height: 48px;
 | 
			
		||||
      letter-spacing: 1px;
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .label {
 | 
			
		||||
      height: 80px;
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      color: #333333;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      margin-bottom: 16px;
 | 
			
		||||
 | 
			
		||||
      & > em {
 | 
			
		||||
        font-style: normal;
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        color: #1365DD;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .file {
 | 
			
		||||
      height: 128px;
 | 
			
		||||
      background: #FFFFFF;
 | 
			
		||||
      border-radius: 8px;
 | 
			
		||||
      border: 1px solid #CCCCCC;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 16px;
 | 
			
		||||
      margin-bottom: 32px;
 | 
			
		||||
 | 
			
		||||
      & > .u-row {
 | 
			
		||||
        height: 100%;
 | 
			
		||||
 | 
			
		||||
        .left {
 | 
			
		||||
          width: 476px;
 | 
			
		||||
          display: flex;
 | 
			
		||||
          align-items: center;
 | 
			
		||||
          word-break: break-all;
 | 
			
		||||
 | 
			
		||||
          & > img {
 | 
			
		||||
            flex-shrink: 0;
 | 
			
		||||
            width: 96px;
 | 
			
		||||
            height: 96px;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          & > span {
 | 
			
		||||
            font-size: 32px;
 | 
			
		||||
            color: #333333;
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            line-height: 44px;
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
            text-overflow: ellipsis;
 | 
			
		||||
            display: -webkit-box;
 | 
			
		||||
            -webkit-box-orient: vertical;
 | 
			
		||||
            -webkit-line-clamp: 2;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > span {
 | 
			
		||||
          font-size: 28px;
 | 
			
		||||
          color: #999999;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .active {
 | 
			
		||||
      background-color: #F3F6F9;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > text {
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      font-size: 30px;
 | 
			
		||||
      color: #649EFD;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .progress {
 | 
			
		||||
      height: 12px;
 | 
			
		||||
      background: #F2F4FC;
 | 
			
		||||
      border-radius: 12px;
 | 
			
		||||
      position: relative;
 | 
			
		||||
      margin: 16px 0 64px 0;
 | 
			
		||||
 | 
			
		||||
      .pro-active {
 | 
			
		||||
        height: 12px;
 | 
			
		||||
        background: #639EFD;
 | 
			
		||||
        border-radius: 12px;
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        left: 0;
 | 
			
		||||
        top: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    em {
 | 
			
		||||
      font-style: normal;
 | 
			
		||||
      font-size: 28px;
 | 
			
		||||
      color: #1365DD;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ::v-deep .u-collapse {
 | 
			
		||||
      position: relative;
 | 
			
		||||
 | 
			
		||||
      &:after {
 | 
			
		||||
        content: "";
 | 
			
		||||
        width: 718px;
 | 
			
		||||
        height: 1px;
 | 
			
		||||
        background-color: rgba(216, 221, 230, 0.5);
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        left: 0;
 | 
			
		||||
        bottom: 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .u-collapse-head {
 | 
			
		||||
        padding: 40px 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .u-collapse-content {
 | 
			
		||||
        font-size: 32px;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        line-height: 48px;
 | 
			
		||||
        letter-spacing: 1px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .footer {
 | 
			
		||||
    height: 112px;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    background: #1365DD;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    font-size: 36px;
 | 
			
		||||
    color: #FFFFFF;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										99
									
								
								src/apps/AppNotification/read.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/apps/AppNotification/read.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="read">
 | 
			
		||||
    <AiTopFixed>
 | 
			
		||||
      <u-tabs :list="tabs" :is-scroll="false" height="96" bar-width="192" :current="current" @change="change"></u-tabs>
 | 
			
		||||
    </AiTopFixed>
 | 
			
		||||
    <div class="body">
 | 
			
		||||
      <div class="item" v-for="(item,index) in (current==0 ? list.read : list.unRead)" :key="index">
 | 
			
		||||
        <u-avatar :src="item.avatar" mode="square" size="76" style="margin-right: 8px;"></u-avatar>
 | 
			
		||||
        <span v-text="item.name"/>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <AiBack/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import {mapActions} from "vuex";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "read",
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      current: 0,
 | 
			
		||||
      list: [],
 | 
			
		||||
      id: null,
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  onLoad(opt) {
 | 
			
		||||
    this.id = opt.id;
 | 
			
		||||
    this.getList();
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    document.title = "接收对象";
 | 
			
		||||
    this.injectJWeixin().then(() => {
 | 
			
		||||
      this.getList();
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['previewFile', 'injectJWeixin']),
 | 
			
		||||
    getList() {
 | 
			
		||||
      this.$http.post("/app/appannouncementreader/list-unread", null, {
 | 
			
		||||
        params: {
 | 
			
		||||
          id: this.id
 | 
			
		||||
        }
 | 
			
		||||
      }).then(res => {
 | 
			
		||||
        if (res && res.data) {
 | 
			
		||||
          this.list = res.data;
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    change(val) {
 | 
			
		||||
      this.current = val;
 | 
			
		||||
      this.list = [];
 | 
			
		||||
      this.getList();
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    tabs() {
 | 
			
		||||
      return [
 | 
			
		||||
        {name: (this.list?.read?.length || 0) + "人已读"},
 | 
			
		||||
        {name: (this.list?.unRead?.length || 0) + "人未读"},
 | 
			
		||||
      ];
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.read {
 | 
			
		||||
  min-height: 100%;
 | 
			
		||||
  background-color: #F5F5F5;
 | 
			
		||||
 | 
			
		||||
  ::v-deep .content {
 | 
			
		||||
    padding: 0 !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .body {
 | 
			
		||||
    padding: 16px 0;
 | 
			
		||||
 | 
			
		||||
    .item {
 | 
			
		||||
      height: 120px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      box-sizing: border-box;
 | 
			
		||||
      padding: 0 50px;
 | 
			
		||||
      background-color: #ffffff;
 | 
			
		||||
      border-bottom: 1px solid #eeeeee;
 | 
			
		||||
 | 
			
		||||
      & > .name {
 | 
			
		||||
        font-size: 36px;
 | 
			
		||||
        font-weight: 600;
 | 
			
		||||
        color: #333333;
 | 
			
		||||
        line-height: 50px;
 | 
			
		||||
        margin-left: 32px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -249,7 +249,7 @@ const store = new Vuex.Store({
 | 
			
		||||
        } else {
 | 
			
		||||
          params = params || {corpId, suiteId}
 | 
			
		||||
        }
 | 
			
		||||
        return http.post("/app/wxcptp/portal/agentSign", null, {
 | 
			
		||||
        return http.post("/app/wxcp/portal/agentSign", null, {
 | 
			
		||||
          params: {...params, url}
 | 
			
		||||
        }).then(res => {
 | 
			
		||||
          if (res?.data) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user