Form.vue 10.5 KB
Newer Older
wanli's avatar
wanli committed
1
<template>
2 3 4 5 6 7 8 9 10
  <a-page-header-wrapper :title="title">
    <a-card :body-style="{ padding: '24px 32px' }" :bordered="false">
      <a-form>
        <a-form-item
          label="标题"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
          :required="true"
        >
11
          <a-input v-model="post.app_name" placeholder="给应用起个名字" />
12 13 14 15 16 17
        </a-form-item>
        <a-form-item
          label="打包算法"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
        >
18
          <a-radio-group v-model="post.algorithm">
19
            <a-radio-button value="zlib"> zlib </a-radio-button>
20
            <a-radio-button value="heatshrink"> heatshrink </a-radio-button>
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
          </a-radio-group>
        </a-form-item>
        <a-form-item
          label="应用版本号"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
          :required="false"
        >
          <a-input v-model="post.app_version" placeholder="请输入版本号" />
        </a-form-item>
        <a-form-item
          label="应用类别"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
          :required="true"
        >
          <a-select
38 39
            v-model="post.category"
            mode="default"
40 41
            style="width: 100%"
            placeholder="应用所属类别"
42
            :allowClear="true"
43
          >
44
            <a-select-option v-for="item in categoryList" :key="item.value">
45
              {{ item.label }}
46 47 48 49 50 51 52 53 54 55 56 57 58
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item
          label="应用ICON"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
          :required="true"
        >
          <a-upload
            name="avatar"
            list-type="picture-card"
            class="avatar-uploader"
59
            :show-upload-list="true"
60 61
            :before-upload="beforeUpload"
            @change="handleLogoChange"
62
            @preview="handlePreview"
63 64 65 66 67 68 69
          >
            <img v-if="imageUrl" :src="imageUrl" alt="avatar" />
            <div v-else>
              <a-icon :type="loading ? 'loading' : 'plus'" />
              <div class="ant-upload-text">上传</div>
            </div>
          </a-upload>
70 71 72 73 74 75 76
          <a-modal
            :visible="previewVisible"
            :footer="null"
            @cancel="handleCancel"
          >
            <img alt="example" style="width: 100%" :src="previewImage" />
          </a-modal>
77 78 79 80 81 82 83
        </a-form-item>
        <a-form-item
          label="适配尺寸"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
          :required="true"
        >
84 85 86 87 88 89 90 91 92 93 94
          <a-select
            :default-value="sizeList[0].label"
            v-model="post.app_screen_size"
            :allowClear="true"
            style="width: 120px"
          >
            <a-select-option
              v-for="item in sizeList"
              :key="item.value"
              :value="item.label"
            >
95 96 97 98 99 100 101 102 103 104
              {{ item.label }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item
          label="适配平台"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
          :required="true"
        >
105 106 107 108 109 110 111 112 113 114 115
          <a-select
            :default-value="portList[0].label"
            v-model="post.app_arch"
            :allowClear="true"
            style="width: 120px"
          >
            <a-select-option
              v-for="item in portList"
              :key="item.value"
              :value="item.label"
            >
116 117 118 119 120 121 122 123 124
              {{ item.label }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item
          label="应用介绍"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
        >
125 126 127 128 129
          <a-textarea
            v-model="post.remarks"
            rows="4"
            placeholder="请输入应用介绍"
          />
130
        </a-form-item>
131 132 133 134 135
        <a-form-item
          label="元信息"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
        >
136 137 138 139 140
          <a-textarea
            v-model="post.meta_data"
            rows="4"
            placeholder="可以存储一些JSON格式应用元信息,接口获取"
          />
141
        </a-form-item>
142 143 144 145 146 147 148 149 150
        <a-form-item
          label="应用源文件"
          :labelCol="{ span: 7 }"
          :wrapperCol="{ span: 10 }"
          :required="true"
        >
          <a-upload-dragger
            name="file"
            :multiple="true"
151
            :before-upload="beforeUpload"
152 153 154 155 156
            @change="handleSourceFileChange"
          >
            <p class="ant-upload-drag-icon">
              <a-icon type="inbox" />
            </p>
157 158
            <p class="ant-upload-text">点击或拖拽文件到此</p>
            <p class="ant-upload-hint">支持单次或批量上传</p>
159 160 161 162 163 164
          </a-upload-dragger>
        </a-form-item>
        <a-form-item
          style="margin-top: 24px"
          :wrapperCol="{ span: 10, offset: 7 }"
        >
165 166 167 168 169 170
          <a-button type="primary" v-if="title == '添加'" @click="onSumbit"
            >提交</a-button
          >
          <a-button style="margin-left: 8px" v-else @click="updateApplication"
            >保存</a-button
          >
171 172 173 174
        </a-form-item>
      </a-form>
    </a-card>
  </a-page-header-wrapper>
wanli's avatar
wanli committed
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
</template>

<script>
import {
  Avatar,
  Row,
  Col,
  Card,
  List,
  Button,
  Form,
  Icon,
  Table,
  Divider,
  Dropdown,
  Input,
  Select,
  Radio,
193 194
  Upload,
  PageHeader,
wanli's avatar
wanli committed
195
  DatePicker,
196
  InputNumber,
197
  message,
wanli's avatar
wanli committed
198 199 200
} from "ant-design-vue";
import PageHeaderWrapper from "@/components/PageHeaderWrapper";
import DescriptionItem from "@/components/DescriptionItem";
201

202 203
import { mapTrim } from "@/utils/index";
import { postApplication, updateApplication } from "@/api/openapi";
204

205 206 207 208 209 210 211 212 213
function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });
}

wanli's avatar
wanli committed
214
export default {
215
  name: "ApplicationForm",
216
  data() {
wanli's avatar
wanli committed
217
    return {
218 219
      previewVisible: false,
      previewImage: "",
220 221
      loading: false,
      imageUrl: "",
222
      uuid: null,
223
      title: "添加",
224
      post: {
225 226 227 228 229 230 231
        app_name: null,
        app_icon: null,
        app_version: null,
        category: null,
        app_screen_size: null,
        app_arch: null,
        remarks: null,
232
        meta_data: null,
233
        logo: null,
234
        fileList: [],
235
      },
236 237 238
      logo: null,
      fileList: [],
      categoryList: [
239 240 241 242 243 244
        { label: "影音视听", value: 1 },
        { label: "实用工具", value: 2 },
        { label: "图书阅读", value: 3 },
        { label: "学习教育", value: 4 },
        { label: "医疗健康", value: 5 },
        { label: "未定义", value: 6 },
245
      ],
246
      sizeList: [
247 248 249
        { label: "240 * 240", value: 1 },
        { label: "390 * 390", value: 2 },
        { label: "450 * 450", value: 3 },
250 251
      ],
      portList: [
252 253
        { label: "ASR3601", value: 1 },
        { label: "ASR3603", value: 2 },
254 255
      ],
    };
wanli's avatar
wanli committed
256 257 258
  },
  components: {
    Icon,
259 260
    AUpload: Upload,
    APageHeader: PageHeader,
wanli's avatar
wanli committed
261 262 263
    ATextarea: Input.TextArea,
    ARadio: Radio,
    ARadioGroup: Radio.Group,
264
    ARadioButton: Radio.Button,
wanli's avatar
wanli committed
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
    AInputNumber: InputNumber,
    AAvatar: Avatar,
    ARow: Row,
    ACol: Col,
    ACard: Card,
    ACardGrid: Card.Grid,
    ACardMeta: Card.Meta,
    AList: List,
    AButton: Button,
    AForm: Form,
    AFormItem: Form.Item,
    AIcon: Icon,
    ATable: Table,
    ADivider: Divider,
    ADropdown: Dropdown,
    AInput: Input,
    ASelect: Select,
282 283
    AUploadDragger: Upload.Dragger,
    ASelectOption: Select.Option,
wanli's avatar
wanli committed
284 285 286 287
    ADescriptionItem: DescriptionItem,
    APageHeaderWrapper: PageHeaderWrapper,
    ARangePicker: DatePicker.RangePicker,
  },
288
  methods: {
289 290 291 292 293 294 295 296 297 298
    handleCancel() {
      this.previewVisible = false;
    },
    async handlePreview(file) {
      if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj);
      }
      this.previewImage = file.url || file.preview;
      this.previewVisible = true;
    },
299 300 301 302 303 304
    handleRemove(file) {
      const index = this.fileList.indexOf(file);
      const newFileList = this.fileList.slice();
      newFileList.splice(index, 1);
      this.fileList = newFileList;
    },
305
    handleLogoChange(file) {
306 307 308
      this.logo = file;
    },
    beforeUpload(file) {
309 310 311 312 313 314
      if (file.size / 1024 / 1024 > 2) {
        message.error("Image must smaller than 2MB!");
      }
      return false;
    },
    handleSourceFileChange(file) {
315
      this.fileList = [...this.fileList, file];
316
      const status = file.file.status;
317

318
      if (status === "done") {
319
        message.success(`${file.file.name} file uploaded successfully.`);
320
      } else if (status === "error") {
321
        message.error(`${file.file.name} file upload failed.`);
322
      }
323 324 325 326 327
    },
    handleUpload() {
      this.uploading = true;

      let formData = new FormData();
328 329
      this.fileList.forEach((item) => {
        formData.append("fileList", item.file);
330
      });
331 332 333 334 335
      formData.append("logo", this.logo.file);
      Object.keys(this.post).forEach((k) => {
        if (this.post[k] && typeof this.post[k] !== "object") {
          formData.append(k, this.post[k]);
        }
336 337
      });

338
      this.postApplication(formData);
339
    },
340
    updateApplication() {
341 342 343 344 345 346 347
      updateApplication(this.uuid, mapTrim(this.post))
        .then((res) => {
          message.success(res.msg);
        })
        .catch((err) => {
          message.error(err.msg);
        });
348
    },
349
    postApplication(formData) {
350 351 352 353 354 355 356 357 358 359 360 361 362
      postApplication(formData)
        .then((res) => {
          this.fileList = [];
          this.logo = null;
          this.post.fileList = [];
          this.post.logo = null;
          this.uploading = false;
          message.success(res.msg);
        })
        .catch((err) => {
          this.uploading = false;
          message.error(err.msg);
        });
363 364
    },
    onSumbit() {
365 366
      this.handleUpload();
    },
367
  },
wanli's avatar
wanli committed
368 369
  computed: {
    desc() {
370 371
      return this.$t("pageDesc");
    },
wanli's avatar
wanli committed
372
  },
373
  created() {
374 375
    const params = this.$route.params;
    console.log(params);
376
    if (params.title) {
377
      this.title = params.title;
378
    }
379 380 381
    if (params.record) {
      this.uuid = params.record.uuid;
      this.post = params.record;
382
    }
383 384
  },
};
wanli's avatar
wanli committed
385 386 387
</script>

<style scoped>
388 389 390 391 392 393 394 395 396 397 398 399 400
.avatar-uploader > .ant-upload {
  width: 128px;
  height: 128px;
}
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
wanli's avatar
wanli committed
401
</style>