linwu 3 тижнів тому
батько
коміт
74474d626f

+ 13 - 0
app/common/model/OfficerAnswerDetailModel.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace app\common\model;
+
+class OfficerAnswerDetailModel extends BaseModel
+{
+    // 设置表名
+    protected $name = 'officer_answer_detail';
+
+    //自动完成
+    protected $autoWriteTimestamp = false;
+
+}

+ 13 - 0
app/common/model/OfficerAnswerModel.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace app\common\model;
+
+class OfficerAnswerModel extends BaseModel
+{
+    // 设置表名
+    protected $name = 'officer_answer';
+
+    //自动完成
+    protected $autoWriteTimestamp = true;
+
+}

+ 13 - 0
app/common/model/OfficerReviewModel.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace app\common\model;
+
+class OfficerReviewModel extends BaseModel
+{
+    // 设置表名
+    protected $name = 'officer_review';
+
+    //自动完成
+    protected $autoWriteTimestamp = false;
+
+}

+ 17 - 0
app/common/model/OfficerReviewSectionModel.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\model;
+
+class OfficerReviewSectionModel extends BaseModel
+{
+    // 设置表名
+    protected $name = 'officer_review_section';
+
+    //自动完成
+    protected $autoWriteTimestamp = false;
+
+    public function titleList()
+    {
+        return $this->hasMany(OfficerReviewTitleModel::class,'rsid','id');
+    }
+}

+ 20 - 0
app/common/model/OfficerReviewTitleModel.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace app\common\model;
+
+class OfficerReviewTitleModel extends BaseModel
+{
+    // 设置表名
+    protected $name = 'officer_review_title';
+
+    //自动完成
+    protected $autoWriteTimestamp = false;
+
+    public function getOptionAttr($value,$data)
+    {
+        if ($value) {
+            return json_decode($value,true);
+        }
+        return [];
+    }
+}

Різницю між файлами не показано, бо вона завелика
+ 4 - 0
app/home/controller/Index.php


+ 68 - 0
app/mobile/controller/Officer.php

@@ -0,0 +1,68 @@
+<?php
+
+namespace app\mobile\controller;
+
+use app\common\model\OfficerAnswerDetailModel;
+use app\common\model\OfficerAnswerModel;
+use app\common\model\OfficerReviewModel;
+use app\common\model\OfficerReviewSectionModel;
+use app\common\model\OfficerReviewTitleModel;
+use app\mobile\MobileBaseController;
+
+class Officer extends MobileBaseController
+{
+    public function index()
+    {
+        $id = input('id');
+        empty($id) && jump('该题库不存在或已删除');
+
+        $review = OfficerReviewModel::find($id);
+        empty($review) && jump('该题库不存在或已删除');
+
+        return view('', [
+            'review' => $review,
+        ]);
+    }
+
+    public function answer()
+    {
+        $id = input('id');
+        empty($id) && jump('该题库不存在或已删除');
+
+        $list = OfficerReviewSectionModel::with(['title_list'])->where('rid', $id)->order('sort', 'desc')->select()->toArray();
+        empty($list) && jump('该题库不存在或已删除');
+
+        return view('', [
+            'id'   => $id,
+            'list' => json_encode($list),
+        ]);
+    }
+
+    public function answerPost()
+    {
+        $id            = input('id');
+        $answer        = input('answer');
+        $answer_detail = input('answer_detail');
+
+        $officer_answer = OfficerAnswerModel::create($answer);
+        $review_title   = OfficerReviewTitleModel::where('rid', $id)->column('option,title', 'no');
+        foreach ($answer_detail as $k => $v) {
+            $options = json_decode($review_title[$k]['option'], true);
+            $option  = $options[$v];
+            OfficerAnswerDetailModel::create([
+                'aid'          => $officer_answer['id'],
+                'no'           => $k,
+                'title'        => $review_title[$k]['title'],
+                'score'        => $option['score'],
+                'option_title' => $option['title'],
+            ]);
+        }
+
+        ajax_return();
+    }
+
+    public function finish()
+    {
+        return view();
+    }
+}

+ 92 - 0
app/mobile/view/officer/answer.html

@@ -0,0 +1,92 @@
+{extend name="public/base"/}
+{block name="css"}
+<style>
+    .title {
+        text-indent: 2em;
+        background: white;
+        padding: 0 10px 20px 10px;
+        font-size: 14px;
+    }
+</style>
+{/block}
+{block name="body"}
+<van-nav-bar
+        class="nav-theme"
+        :fixed="true"
+        :placeholder="true"
+>
+    <template #title>
+        <span class="text-white">人资测评系统</span>
+    </template>
+</van-nav-bar>
+<van-steps :active="active">
+    <van-step>基础信息</van-step>
+    <van-step v-for="(item,key) in list" :key="item.id">{{key + 1}}</van-step>
+</van-steps>
+<div v-show="active==0">
+    {include file="officer/answer_base"/}
+</div>
+<div v-for="(item,index) in list" :key="'list_' + item.id" v-show="active==index+1">
+    <div class="title">{{item.name}}</div>
+    <van-radio-group v-model="answer_detail[title_item.no]" style="margin-top:10px" :key="'title_' + title_item.id" v-for="(title_item,title_index) in item.title_list">
+        <van-cell-group>
+            <van-cell :title="title_item.no + '.' + title_item.title"></van-cell>
+            <van-cell :title="option_item.title" clickable @click="answer_detail[title_item.no] = option_index" :key="'option_' + title_item.id + '_' + option_index" v-for="(option_item,option_index) in title_item.option">
+                <template #right-icon>
+                    <van-radio :name="option_index" ></van-radio>
+                </template>
+            </van-cell>
+        </van-cell-group>
+    </van-radio-group>
+    <div style="margin: 16px;display: flex;align-items: center;justify-content: space-around;">
+        <div style="width:40%">
+            <van-button type="success" size="large" @click="onStep(index)">
+                上一步
+            </van-button>
+        </div>
+        <div style="width:40%">
+            <van-button type="primary" size="large" @click="onStep(index+2)" v-show="list.length > index+1">
+                下一步
+            </van-button>
+            <van-button type="primary" size="large" @click="onSubmit" v-show="list.length <= index+1">
+                提交
+            </van-button>
+        </div>
+    </div>
+</div>
+{/block}
+{block name="script"}
+<script>
+    function v_setup() {
+        let base = answer_base();
+
+        base.list = {$list};
+        let sum = 0;
+        for (let item of base.list) {
+            sum += item.title_list.length;
+        }
+
+        base.active = Vue.ref(0);
+        base.onStep = (active) => {
+            base.active.value = active;
+        }
+        base.onSubmit = () => {
+            for (let i = 0; i < sum; i++) {
+                if (base.answer_detail.value[i+1] === undefined) {
+                    vant.showToast(`第${i+1}题未填写`);
+                    return false;
+                }
+            }
+            base.answer.value.rid = {$id};
+            postJson("{:url('officer/answerPost')}",{id:{$id},answer:base.answer.value,answer_detail:base.answer_detail.value}).then((data) => {
+                vant.showToast('提交成功');
+                location.href = "{:url('officer/finish')}";
+            })
+        }
+
+        base.answer_detail = Vue.ref({});
+
+        return base;
+    }
+</script>
+{/block}

+ 338 - 0
app/mobile/view/officer/answer_base.html

@@ -0,0 +1,338 @@
+<van-cell-group>
+    <van-field
+            v-model="answer.name"
+            label="姓名"
+            placeholder="请输入姓名"
+            required
+    ></van-field>
+    <van-field
+            v-model="answer.mobile"
+            label="手机号"
+            placeholder="请输入手机号"
+            required
+    ></van-field>
+    <van-field
+            v-model="answer.sex"
+            label="性别"
+            placeholder="请选择性别"
+            is-link
+            readonly
+            required
+            @click="showSex = true"
+    ></van-field>
+    <van-popup v-model:show="showSex" round position="bottom">
+        <van-picker
+                :columns="sex_list"
+                @cancel="showSex = false"
+                @confirm="onSexConfirm"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            v-model="answer.age"
+            label="年龄"
+            placeholder="请输入年龄"
+            required
+    ></van-field>
+    <van-field
+            v-model="answer.marry"
+            label="婚姻状况"
+            placeholder="请选择婚姻状况"
+            is-link
+            readonly
+            required
+            @click="showMarry = true"
+    ></van-field>
+    <van-popup v-model:show="showMarry" round position="bottom">
+        <van-picker
+                :columns="marry_list"
+                @cancel="showMarry = false"
+                @confirm="onMarryConfirm"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            v-model="answer.education"
+            label="学历"
+            placeholder="请选择学历"
+            is-link
+            readonly
+            required
+            @click="showEducation = true"
+    ></van-field>
+    <van-popup v-model:show="showEducation" round position="bottom">
+        <van-picker
+                :columns="education_list"
+                @cancel="showEducation = false"
+                @confirm="onEducationConfirm"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            v-model="answer.major"
+            label="所修专业"
+            placeholder="若有多个学历,以最高学历专业为准"
+            required
+    ></van-field>
+    <van-field
+            v-model="answer.seniority"
+            label="工龄"
+            placeholder="累计工作年限"
+            required
+    >
+        <template #right-icon>年</template>
+    </van-field>
+    <van-field
+            v-model="answer.leader"
+            label="担任领导的累计年限"
+            placeholder="含各类、各级领导职务"
+            required
+            label-align="top"
+    >
+        <template #right-icon>年</template>
+    </van-field>
+    <van-field
+            v-model="answer.industry"
+            label="所在行业"
+            placeholder="所在行业"
+            required
+    ></van-field>
+    <van-field
+            v-model="answer.company"
+            label="单位性质"
+            placeholder="请选择所在单位性质"
+            is-link
+            readonly
+            required
+            @click="showCompany = true"
+    ></van-field>
+    <van-popup v-model:show="showCompany" round position="bottom">
+        <van-picker
+                :columns="company_list"
+                @cancel="showCompany = false"
+                @confirm="onCompanyConfirm"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            v-model="answer.company_text"
+            :label="company_title"
+            :placeholder="company_placeholder"
+            required
+            v-show="showCompanyText"
+    ></van-field>
+    <van-field
+            v-model="answer.job"
+            label="职位"
+            placeholder="请选择职位"
+            is-link
+            readonly
+            required
+            @click="showJob = true"
+            v-show="showJobField"
+    ></van-field>
+    <van-popup v-model:show="showJob" round position="bottom">
+        <van-picker
+                :columns="job_list"
+                @cancel="showJob = false"
+                @confirm="onJobConfirm"
+        ></van-picker>
+    </van-popup>
+    <van-field
+            v-model="answer.job_text"
+            label="具体职位"
+            placeholder="请注明具体职位"
+            required
+            v-show="showJobText"
+    ></van-field>
+</van-cell-group>
+<div style="margin: 16px;">
+    <van-button block type="primary" size="large" @click="baseSubmit">
+        下一步
+    </van-button>
+</div>
+<script>
+    function answer_base() {
+        let base = {};
+
+        base.answer = Vue.ref({});
+        //年龄
+        base.sex_list = [
+            {text: '男', value: '男'},
+            {text: '女', value: '女'},
+        ];
+        base.showSex = Vue.ref(false);
+        base.onSexConfirm = ({selectedValues}) => {
+            base.answer.value.sex = selectedValues[0];
+            base.showSex.value = false;
+        };
+
+        //婚姻状况
+        base.marry_list = [
+            {text: '单身/未婚', value: '单身/未婚'},
+            {text: '已婚', value: '已婚'},
+            {text: '离婚', value: '离婚'},
+        ];
+        base.showMarry = Vue.ref(false);
+        base.onMarryConfirm = ({selectedValues}) => {
+            base.answer.value.marry = selectedValues[0];
+            base.showMarry.value = false;
+        };
+
+        //学历
+        base.education_list = [
+            {text: '初中及以下', value: '初中及以下'},
+            {text: '高中/职校/中专', value: '高中/职校/中专'},
+            {text: '大专', value: '大专'},
+            {text: '本科', value: '本科'},
+            {text: '硕士', value: '硕士'},
+            {text: '博士', value: '博士'},
+        ];
+        base.showEducation = Vue.ref(false);
+        base.onEducationConfirm = ({selectedValues}) => {
+            base.answer.value.education = selectedValues[0];
+            base.showEducation.value = false;
+        };
+
+        //单位
+        base.company_list = [
+            {text: '党政机关', value: '党政机关'},
+            {text: '事业单位', value: '事业单位'},
+            {text: '国有企业', value: '国有企业'},
+            {text: '民营企业', value: '民营企业'},
+            {text: '外商独资企业', value: '外商独资企业'},
+            {text: '合资/合作企业', value: '合资/合作企业'},
+            {text: '股份制(所有权混合)企业', value: '股份制(所有权混合)企业'},
+            {text: '个体工商户', value: '个体工商户'},
+            {text: '社会团体/行业组织', value: '社会团体/行业组织'},
+            {text: '其他', value: '其他'},
+        ];
+        base.showCompany = Vue.ref(false);
+        base.showCompanyText = Vue.ref(false);
+        base.onCompanyConfirm = ({selectedValues}) => {
+            if (selectedValues[0] == '党政机关') {
+                base.company_title.value = '具体部门'
+                base.company_placeholder.value = '党政机关的具体部门'
+                base.showCompanyText.value = true;
+                base.showJobField.value = true;
+                base.job_list.value = base.job_list_1;
+            } else if (selectedValues[0] == '事业单位') {
+                base.company_title.value = '具体领域'
+                base.company_placeholder.value = '事业单位的具体领域'
+                base.showCompanyText.value = true;
+                base.showJobField.value = true;
+                base.job_list.value = base.job_list_1;
+            } else if (selectedValues[0] == '其他') {
+                base.company_title.value = '单位补充'
+                base.company_placeholder.value = '请填写单位的性质'
+                base.showCompanyText.value = true;
+                base.showJobField.value = false;
+            } else {
+                base.job_list.value = base.job_list_2;
+                base.showCompanyText.value = false;
+                base.showJobField.value = true;
+            }
+
+            base.answer.value.job = '';
+            base.answer.value.job_text = '';
+            base.showJobText.value = false;
+            base.answer.value.company = selectedValues[0];
+            base.answer.value.company_text = '';
+            base.showCompany.value = false;
+            console.log(Vue.toRaw(base.answer.value),Vue.toRaw(base.job_list.value));
+        };
+        base.company_title = Vue.ref('');
+        base.company_placeholder = Vue.ref('');
+
+        //职位
+        base.job_list_1 = [
+            {text: '省/部级(含副省/部级)', value: '省/部级(含副省/部级)'},
+            {text: '厅/局/司级(含副厅/局/司级)', value: '厅/局/司级(含副厅/局/司级)'},
+            {text: '处级(含副处级)', value: '处级(含副处级)'},
+            {text: '科级(含副科级)', value: '科级(含副科级)'},
+            {text: '一般工作人员', value: '一般工作人员'},
+            {text: '其他', value: '其他'},
+        ];
+        base.job_list_2 = [
+            {text: '老总(含董事级成员)', value: '老总(含董事级成员)'},
+            {text: '高层管理者', value: '高层管理者'},
+            {text: '中层管理者', value: '中层管理者'},
+            {text: '一线(基层)管理者', value: '一线(基层)管理者'},
+            {text: '一般职员', value: '一般职员'},
+            {text: '其他', value: '其他'},
+        ];
+        base.job_list = Vue.ref([]);
+        base.showJob = Vue.ref(false);
+        base.showJobField = Vue.ref(false);
+        base.showJobText = Vue.ref(false);
+        base.onJobConfirm = ({selectedValues}) => {
+            base.answer.value.job = selectedValues[0];
+            base.answer.value.job_text = '';
+            base.showJob.value = false;
+            if (selectedValues[0] == '其他') {
+                base.showJobText.value = true;
+            }
+        };
+
+        base.baseSubmit = () => {
+            const required_field = [
+                // {field:'name',tip:'请输入姓名'},
+                // {field:'mobile',tip:'请输入手机号'},
+                // {field:'sex',tip:'请选择性别'},
+                // {field:'age',tip:'请输入年龄'},
+                // {field:'marry',tip:'请选择婚姻状况'},
+                // {field:'education',tip:'请选择学历'},
+                // {field:'major',tip:'请输入所修专业'},
+                // {field:'seniority',tip:'请输入工龄'},
+                // {field:'leader',tip:'请输入担任领导的累计年限'},
+                // {field:'industry',tip:'请输入所在行业'},
+                {field:'company',tip:'请选择单位性质'},
+            ];
+            for (let item of required_field) {
+                if (base.answer.value[item.field] === undefined || base.answer.value[item.field] === '') {
+                    vant.showToast(item.tip);
+                    return false;
+                }
+            }
+            if (base.answer.value.company == '党政机关') {
+                if (base.answer.value.company_text === undefined || base.answer.value.company_text === '') {
+                    vant.showToast('请输入具体部门');
+                    return false;
+                }
+                if (base.answer.value.job === undefined || base.answer.value.job === '') {
+                    vant.showToast('请选择职位');
+                    return false;
+                } else {
+                    if (base.answer.value.job == '其他') {
+                        if (base.answer.value.job_text === undefined || base.answer.value.job_text === '') {
+                            vant.showToast('请输入具体职位');
+                            return false;
+                        }
+                    }
+                }
+            }
+            if (base.answer.value.company == '事业单位') {
+                if (base.answer.value.company_text === undefined || base.answer.value.company_text === '') {
+                    vant.showToast('请输入具体领域');
+                    return false;
+                }
+                if (base.answer.value.job === undefined || base.answer.value.job === '') {
+                    vant.showToast('请选择职位');
+                    return false;
+                } else {
+                    if (base.answer.value.job == '其他') {
+                        if (base.answer.value.job_text === undefined || base.answer.value.job_text === '') {
+                            vant.showToast('请输入具体职位');
+                            return false;
+                        }
+                    }
+                }
+            }
+            if (base.answer.value.company == '其他') {
+                if (base.answer.value.company_text === undefined || base.answer.value.company_text === '') {
+                    vant.showToast('请输入单位补充');
+                    return false;
+                }
+            }
+            base.active.value = 1;
+        }
+
+        return base;
+    }
+</script>

+ 40 - 0
app/mobile/view/officer/finish.html

@@ -0,0 +1,40 @@
+{extend name="public/base"/}
+{block name="css"}
+<style>
+    .icon{
+        text-align:center;
+        margin-top:50px;
+    }
+
+    .msg{
+        text-align:center;
+        margin:0;
+        padding:0;
+        font-size:24px;
+    }
+
+</style>
+{/block}
+{block name="body"}
+<van-nav-bar
+        class="nav-theme"
+        :fixed="true"
+        :placeholder="true"
+>
+    <template #title>
+        <span class="text-white">提示</span>
+    </template>
+</van-nav-bar>
+<div style="width:100%;height:46px;"></div>
+<div class="icon">
+    <van-icon name="warning-o" size="160" color="#0081ff"></van-icon>
+</div>
+<h3 class="msg">提交成功</h3>
+{/block}
+{block name="script"}
+<script>
+    function v_setup() {
+        return {};
+    }
+</script>
+{/block}

+ 37 - 0
app/mobile/view/officer/index.html

@@ -0,0 +1,37 @@
+{extend name="public/base"/}
+{block name="css"}
+<style>
+    .title {margin-top:50px;}
+    .title p{margin:10px auto;padding:0 20px;text-align: center;font-size:18px;font-weight: 700;}
+</style>
+{/block}
+{block name="body"}
+<van-nav-bar
+        class="nav-theme"
+        :fixed="true"
+        :placeholder="true"
+>
+    <template #title>
+        <span class="text-white">人资测评系统</span>
+    </template>
+</van-nav-bar>
+<div class="title">{$review.name}</div>
+<div style="margin: 100px 20px;">
+    <van-button block type="primary" size="large" @click="toStart">
+        开始测评
+    </van-button>
+</div>
+{/block}
+{block name="script"}
+<script>
+    function v_setup() {
+        let base = {};
+
+        base.toStart = () => {
+            location.href = "{:url('officer/answer')}?id={$review.id}"
+        }
+
+        return base;
+    }
+</script>
+{/block}

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
public/static/mobile/css/vant4.6.min.css


Деякі файли не було показано, через те що забагато файлів було змінено