guhongwei 4 anni fa
parent
commit
f9cdb6071c

+ 1 - 1
package.json

@@ -1,5 +1,5 @@
 {
-  "name": "",
+  "name": "mobile-official",
   "version": "0.1.0",
   "private": true,
   "scripts": {

+ 6 - 0
src/router/index.js

@@ -182,6 +182,12 @@ const routes = [
     meta: { title: '审核详情', isleftarrow: true },
     component: () => import('../views/adminCenter/transaction/detail.vue'),
   },
+  // 问卷调查
+  {
+    path: '/question/detail',
+    meta: { title: '问卷调查填写', isleftarrow: false },
+    component: () => import('../views/question/detail.vue'),
+  },
   // 公众号第一版结束
   // 公众号第二版开始 viewTwo
   // 在线展会

+ 8 - 0
src/store/index.js

@@ -40,6 +40,10 @@ import productpact from './market/productpact';
 import authUser from './user/auth-user';
 // e专利
 import patent from './market/patent';
+// 问卷调查
+import answer from './question/answer';
+import question from './question/question';
+import questionnaire from './question/questionnaire';
 
 // 公共
 import * as ustate from '@/store/common/state';
@@ -93,5 +97,9 @@ export default new Vuex.Store({
     scienceNews,
     // e专利
     patent,
+    // 问卷调查
+    answer,
+    question,
+    questionnaire,
   },
 });

+ 44 - 0
src/store/question/answer.js

@@ -0,0 +1,44 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  answer: `/api/question/answer`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(api.answer, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.answer}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.answer}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.answer}/update/${id}`, {
+      ...info,
+    });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.answer}/${payload}`);
+    return res;
+  },
+  async findAnswer({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.answer}/getAnswer`, payload);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 40 - 0
src/store/question/question.js

@@ -0,0 +1,40 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  question: `/api/question/question`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(api.question, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.question}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.question}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.question}/update/${id}`, {
+      ...info,
+    });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.question}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 40 - 0
src/store/question/questionnaire.js

@@ -0,0 +1,40 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  questionnaire: `/api/question/questionnaire`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(api.questionnaire, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.questionnaire}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.questionnaire}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.questionnaire}/update/${id}`, {
+      ...info,
+    });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.questionnaire}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 173 - 0
src/views/question/detail copy.vue

@@ -0,0 +1,173 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <el-col :span="24" class="info">
+            <el-col :span="24" class="title">
+              {{ info.title }}
+            </el-col>
+            <el-col :span="24" class="brief">
+              {{ info.brief }}
+            </el-col>
+          </el-col>
+          <el-col :span="24" class="one">
+            <van-form @submit="onSubmit">
+              <van-row>
+                <van-col span="24">
+                  您是否愿意成为平台用户
+                </van-col>
+                <van-col span="24">
+                  <van-radio-group v-model="form.webUser" direction="horizontal">
+                    <van-radio name="1">是</van-radio>
+                    <van-radio name="2">否</van-radio>
+                  </van-radio-group>
+                </van-col>
+              </van-row>
+              <van-row v-if="form.webUser == '1'">
+                <van-col span="24">
+                  联系电话
+                </van-col>
+                <van-col span="24">
+                  <van-field v-model="form.phone" type="tel" name="手机号" placeholder="手机号" />
+                </van-col>
+              </van-row>
+              <van-row v-for="(item, index) in info.questions" :key="index">
+                <van-col span="24">
+                  {{ item.title }}
+                </van-col>
+                <van-col span="24">
+                  <van-field name="radio">
+                    <template #input>
+                      <van-radio-group v-model="form.radio" direction="horizontal">
+                        <van-radio :name="i.name" v-for="(i, index) in item.selects" :key="index">{{ i.num }}.{{ i.name }}</van-radio>
+                      </van-radio-group>
+                    </template>
+                  </van-field>
+                </van-col>
+              </van-row>
+              <!-- <van-field v-model="form.phone" type="tel" name="手机号" label="手机号" placeholder="手机号" v-if="form.webUser == '1'" />
+              <van-row v-for="(item, index) in info.questions" :key="index">
+                <span v-if="item.type == '0'">
+                  单选
+                </span>
+                <span v-else-if="item.type == '1'">
+                  多选
+                </span>
+                <span v-else-if="item.type == '2'">
+                  简答
+                </span>
+              </van-row> -->
+              <div style="margin: 16px;">
+                <van-button round block type="info" native-type="submit">提交</van-button>
+              </div>
+            </van-form>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/layout/common/topInfo.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: questionnaire } = createNamespacedHelpers('questionnaire');
+export default {
+  name: 'detail',
+  props: {},
+  components: { NavBar },
+  data: function() {
+    return {
+      // 头部标题
+      title: '',
+      // meta为true
+      isleftarrow: '',
+      // 返回
+      navShow: true,
+      // 问卷详情
+      info: {},
+      form: {},
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...questionnaire(['fetch']),
+    async search() {
+      if (this.id) {
+        let res = await this.fetch(this.id);
+        if (this.$checkRes(res)) {
+          this.$set(this, `info`, res.data);
+        }
+      }
+    },
+    // 提交
+    onSubmit() {
+      let data = this.form;
+      console.log(data);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id || '606d12e056b552081848e8f8';
+    },
+  },
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {},
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+}
+.main {
+  min-height: 570px;
+  padding: 0 10px;
+  .info {
+    border-bottom: 1px dashed #ccc;
+    padding: 15px 0;
+    margin: 0 0 10px 0;
+    .title {
+      text-align: center;
+      font-size: 18px;
+      font-weight: bold;
+      margin: 0 0 10px 0;
+    }
+    .brief {
+      font-size: 16px;
+      text-align: center;
+    }
+  }
+  // .one {
+  //   margin: 0 0 10px 0;
+  //   .title {
+  //     padding: 10px 0px;
+  //   }
+  //   .change {
+  //     .van-radio-group {
+  //       margin: 0 0 10px 0;
+  //     }
+  //   }
+  // }
+}
+</style>

+ 271 - 0
src/views/question/detail.vue

@@ -0,0 +1,271 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <el-col :span="24" class="info">
+            <el-col :span="24" class="title">
+              {{ question.title }}
+            </el-col>
+            <el-col :span="24" class="brief">
+              {{ question.brief }}
+            </el-col>
+          </el-col>
+          <el-col :span="24" class="one">
+            <el-col :span="24" class="form">
+              <el-form :model="answer" label-position="top" ref="form">
+                <el-form-item v-if="!user || !user.id" label="您是否注册成为平台用户" class="user">
+                  <el-radio-group v-model="userForm.user">
+                    <el-radio :label="true">是</el-radio>
+                    <el-radio :label="false">否</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+                <el-form-item v-if="userForm.user">
+                  <el-input v-model="userForm.phone" placeholder="请填写手机号"></el-input>
+                </el-form-item>
+                <!-- 0单选,1多选,2简答 -->
+                <template v-for="(i, index) in question.questions">
+                  <el-form-item
+                    v-if="i.type === '0'"
+                    :prop="`${index}`"
+                    :key="`question${index}`"
+                    :label="`${index + 1}.${i.title}`"
+                    :rules="[{ required: true, message: '请选择一个选项', trigger: 'blur' }]"
+                  >
+                    <el-radio-group v-model="answer[index]" :disabled="disabled">
+                      <el-radio v-for="(s, si) in i.selects" :key="`s_${index}_${si}`" :label="s.name">{{ s.num }}.{{ s.name }}</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                  <el-form-item
+                    v-else-if="i.type === '1'"
+                    :prop="`${index}`"
+                    :key="`question${index}`"
+                    :label="`${index + 1}.${i.title}`"
+                    :rules="[{ required: true, message: '请至少选择一个选项', trigger: 'blur' }]"
+                  >
+                    <el-checkbox-group :value="answer[index]" @input="data => toCheck(data, index)" :disabled="disabled">
+                      <el-checkbox v-for="(s, si) in i.selects" :key="`c_${index}_${si}`" :label="s.name">{{ s.num }}.{{ s.name }}</el-checkbox>
+                    </el-checkbox-group>
+                  </el-form-item>
+                  <el-form-item v-else :key="`question${index}`" :label="`${index + 1}.${i.title}`">
+                    <el-input v-model="answer[index]" type="textarea" :autosize="{ minRows: 4, maxRows: 6 }" :readonly="disabled"></el-input>
+                  </el-form-item>
+                </template>
+              </el-form>
+            </el-col>
+            <el-col :span="24" class="btn">
+              <el-button type="primary" size="mini" @click="toSubmit" v-if="!disabled">提交</el-button>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/layout/common/topInfo.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: questionnaire } = createNamespacedHelpers('questionnaire');
+const { mapActions: answer } = createNamespacedHelpers('answer');
+export default {
+  name: 'detail',
+  props: {},
+  components: { NavBar },
+  data: function() {
+    return {
+      // 头部标题
+      title: '',
+      // meta为true
+      isleftarrow: '',
+      // 返回
+      navShow: true,
+      // 问卷详情
+      question: {},
+      answer: {},
+      test: [],
+      disabled: false,
+      userForm: {},
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...questionnaire(['fetch']),
+    ...answer(['create', 'findAnswer']),
+    async search() {
+      const res = await this.fetch(this.id);
+      if (this.$checkRes(res)) {
+        const { questions } = res.data;
+        for (let i = 0; i < questions.length; i++) {
+          const e = questions[i];
+          const { select, type } = e;
+          if (type === '1') {
+            this.answer[i] = [];
+          }
+        }
+        this.$set(this, `question`, res.data);
+      }
+      this.getAnswer();
+    },
+    async getAnswer() {
+      if (!this.user || !this.user.id) return;
+      const res = await this.findAnswer({ user_id: this.user.id, questionnaire_id: this.id });
+      if (this.$checkRes(res)) {
+        if (res.data) {
+          this.disabled = true;
+          // 还原数据
+          const { answer } = res.data;
+          const questions = this.question.questions;
+          const reply = {};
+          for (const i of answer) {
+            const { answer: a, quest } = i;
+            const r = questions.findIndex(f => f.title === quest);
+            if (r > -1) reply[r] = a;
+          }
+          this.$set(this, 'answer', reply);
+        }
+      }
+    },
+    // 因为层级过深(只要不是在this下,就属于过深),所以需要手动更新视图
+    toCheck(data, model) {
+      this.answer[model] = data;
+      this.$forceUpdate();
+    },
+    async toSubmit() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.submit();
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    async submit() {
+      let dup = _.cloneDeep(this.answer);
+      const keys = Object.keys(dup);
+      const questions = this.question.questions;
+      const answer = [];
+      for (const i of keys) {
+        const a = dup[i];
+        const quest = questions[i];
+        if (a && quest) {
+          const obj = { answer: a, quest: quest.title };
+          answer.push(obj);
+        }
+      }
+      const data = {
+        questionnaire_id: this.id,
+        answer,
+      };
+      if (this.user && this.user.id) {
+        data.user_id = this.user.id;
+      } else {
+        const userForm = this.userForm;
+        if (userForm.user) data.phone = userForm.phone;
+      }
+      const res = await this.create(data);
+      if (this.$checkRes(res)) {
+        this.$notify({
+          message: '提交成功',
+          type: 'success',
+        });
+      } else {
+        this.$notify({
+          message: '提交失败',
+          type: 'erroe',
+        });
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id || '606d50faf4b5be32a427db06';
+    },
+  },
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {},
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+}
+.main {
+  min-height: 570px;
+  padding: 0 10px;
+  .info {
+    border-bottom: 1px dashed #ccc;
+    padding: 15px 0;
+    margin: 0 0 10px 0;
+    .title {
+      text-align: center;
+      font-size: 18px;
+      font-weight: bold;
+      margin: 0 0 10px 0;
+    }
+    .brief {
+      font-size: 16px;
+      text-align: center;
+    }
+  }
+  .one {
+    padding: 10px 0;
+    .form {
+      .user {
+        margin: 0 !important;
+        width: 100%;
+        /deep/.el-radio {
+          width: 15%;
+        }
+      }
+      /deep/.el-form-item {
+        margin-bottom: 15px;
+        padding: 0 0 10px 0;
+      }
+      /deep/.el-form-item__content {
+        line-height: 15px;
+      }
+      /deep/.el-form-item__label {
+        line-height: 10px;
+        font-size: 13px;
+        font-weight: bold;
+        color: #000;
+      }
+      /deep/.el-radio-group {
+        width: 100%;
+        /deep/.el-radio {
+          width: 45%;
+          margin: 0 10px 10px 0;
+        }
+      }
+      /deep/.el-checkbox {
+        line-height: 15px;
+      }
+    }
+    .btn {
+      text-align: center;
+    }
+  }
+}
+</style>