123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- <template>
- <view class="content">
- <form @submit="formSubmit">
- <view class="value other">
- <view class="title">问题类型</view>
- <view class="label">
- <picker @change="typeChange" :range="typeList" range-key='label'>
- <view class="picker">{{form.type_name||'请选择 >'}}</view>
- </picker>
- <span v-if="errors.type" class="error-message">{{ errors.type }}</span>
- </view>
- </view>
- <view class="brief other margin">
- <view class="title">问题描述</view>
- <view class="label">
- <textarea name='brief' :value="form.brief" placeholder="请写下您的建议,如功能需求、产品吐槽等,我们会努力改进" auto-height />
- <span v-if="errors.brief" class="error-message">{{ errors.brief }}</span>
- </view>
- </view>
- <view class="brief other margin">
- <view class="title">图片(可上传三张)</view>
- <view class="label">
- <up-upload :fileList="form.file" @afterRead="afterRead" @delete="deletePic" name="icon" multiple
- :maxCount="3"></up-upload>
- </view>
- </view>
- <view class="button">
- <button type="warn" size="mini" form-type="submit">保存</button>
- </view>
- </form>
- <view class="view" @click="toView">查看历史反馈</view>
- </view>
- </template>
- <script setup lang="ts">
- import moment from 'moment';
- import { inject, computed, ref } from 'vue';
- //该依赖已内置不需要单独安装
- import { onShow, onPullDownRefresh } from "@dcloudio/uni-app";
- // 请求接口
- const $api = inject('$api');
- const $apifile = inject('$apifile');
- // 表单
- const form = ref({ file: [] });
- // 字典表
- const typeList = ref([]);
- const errors = ref({});
- // user
- const user = computed(() => {
- return uni.getStorageSync('user');
- })
- onShow(async () => {
- await searchOther();
- })
- // 其他查询信息
- const searchOther = async () => {
- let res;
- // 问题类型
- res = await $api(`dictData`, 'GET', { code: 'opinionType', is_use: '0' });
- if (res.errcode === 0) typeList.value = res.data;
- };
- // 学历类型选择
- const typeChange = (e) => {
- const data = typeList.value[e.detail.value]
- if (data) {
- form.value.type = data.value
- form.value.type_name = data.label
- }
- };
- // 删除图片
- const deletePic = (event) => {
- const file = form.value.file.filter(i => i.url !== event.file.url)
- form.value.file = file
- };
- // 新增图片
- const afterRead = async (event) => {
- const url = event.file[0].url
- const result = await $apifile(`/web/learn_opinion/upload`, 'file', url, 'file');
- if (result.errcode === 0) form.value.file = [...form.value.file, ...[result]]
- };
- // 自定义的验证函数
- const validateObject = (obj : any) => {
- const errors : any = {};
- if (!obj.type || obj.type.trim() === '') {
- errors.type = '请填写问题类型!';
- }
- if (!obj.brief || obj.brief.trim() === '') {
- errors.brief = '请填写问题描述!';
- }
- // 如果有错误,返回错误对象
- if (Object.keys(errors).length > 0) {
- return errors;
- }
- // 如果没有错误,返回null或undefined
- return null;
- }
- // 处理两个对象合并
- const mergeObjectsWithoutDuplicates = async (obj1, obj2) => {
- return Object.keys({ ...obj1, ...obj2 }).reduce((acc, key) => {
- if (!acc.hasOwnProperty(key)) {
- if (key == 'type_name') {
- delete acc[key]
- } else {
- // 如果累加器对象(acc)中不存在该键,则添加它
- acc[key] = obj1.hasOwnProperty(key) ? obj1[key] : obj2[key];
- }
- }
- return acc;
- }, {});
- }
- // 保存
- const formSubmit = async (e) => {
- // 调用验证函数
- const data : any = await mergeObjectsWithoutDuplicates(e.detail.value, form.value);
- const errorsInfo = await validateObject(data);
- // 检查是否有错误
- if (errorsInfo) {
- errors.value = errorsInfo
- // 遍历错误对象并显示错误信息
- for (const key in errorsInfo) {
- if (errorsInfo.hasOwnProperty(key)) {
- console.error(`${key} 错误: ${errorsInfo[key]}`);
- }
- }
- } else {
- errors.value = {}
- data.user = user.value._id
- if (user.value.role_type == 'Student') data.userType = '1'
- else data.userType = '0'
- data.time = moment().format('YYYY-MM-DD HH:mm:ss')
- const res = await $api(`opinion`, 'POST', data);
- if (res.errcode == '0') {
- uni.showToast({
- title: '反馈成功!',
- icon: 'success'
- });
- uni.navigateBack({
- delta: 1
- })
- }
- }
- };
- // 查看历史反馈
- const toView = () => {
- uni.navigateTo({
- url: `/pagesMy/opinion/list`
- })
- }
- </script>
- <style lang="scss" scoped>
- .content {
- display: flex;
- flex-direction: column;
- min-height: 100vh;
- background-color: var(--f1Color);
- .margin {
- margin: 3vw 0 0 0;
- }
- .other {
- padding: 3vw 2vw;
- border-bottom: 1px solid var(--footColor);
- }
- .value {
- display: flex;
- justify-content: space-between;
- align-items: center;
- background-color: var(--mainColor);
- .label {
- text-align: right;
- .input {
- text-align: right;
- }
- .image {
- width: 15vw;
- height: 15vw;
- border-radius: 20vw;
- }
- .error-message {
- margin: 5px 0 0 0;
- color: var(--ff0Color);
- font-size: var(--font12Size);
- }
- }
- }
- .brief {
- background-color: var(--mainColor);
- .title {
- margin: 0 0 2vw 0;
- }
- .label {
- .error-message {
- margin: 5px 0 0 0;
- color: var(--ff0Color);
- font-size: var(--font12Size);
- }
- }
- }
- .button {
- text-align: center;
- margin: 2vw 0 0 0;
- button {
- width: 80%;
- font-size: var(--font16Size);
- color: var(--mainColor);
- background-color: var(--3c9Color);
- border-radius: 10vw;
- margin: 0 2vw;
- }
- }
- .view {
- width: 100%;
- position: fixed;
- bottom: 2vw;
- left: 0;
- text-align: center;
- color: var(--3c9Color);
- font-size: var(--font12Size);
- }
- }
- </style>
|