|
|
@@ -0,0 +1,472 @@
|
|
|
+<template>
|
|
|
+ <div class="sign-new-project">
|
|
|
+ <div class="sign-new-tips">
|
|
|
+ 项目是最重要的信息;据客栈统计,<b>83%</b>的客户特别倾向有类似项目经历,且信息完善的开发者!
|
|
|
+ </div>
|
|
|
+ <div class="sign-project-main">
|
|
|
+ <header class="sign-new-header">
|
|
|
+ <div class="sign-new-header-title">作品(3-5个项目)</div>
|
|
|
+ </header>
|
|
|
+
|
|
|
+ <section class="sign-new-works-list">
|
|
|
+ <div v-if="works.length > 0">
|
|
|
+ <template v-for="(item, idx) in works">
|
|
|
+ <div
|
|
|
+ v-if="editingItem.indexOf(idx) < 0"
|
|
|
+ :key="`works_${idx}`"
|
|
|
+ class="show"
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ class="image"
|
|
|
+ :style="{
|
|
|
+ 'background-image': `url('${works[idx].image_list[0].url}')`
|
|
|
+ }"
|
|
|
+ v-if="works[idx].image_list && works[idx].image_list[0]"
|
|
|
+ >
|
|
|
+ </span>
|
|
|
+ <div class="des">
|
|
|
+ <div class="des-title">
|
|
|
+ <div class="des-title-name text-line-1">{{ item.name }}</div>
|
|
|
+ <div class="des-title-time">{{ item.update_time_name }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="des-content text-line-3">
|
|
|
+ {{ item.description }}
|
|
|
+ </div>
|
|
|
+ <div class="des-state">
|
|
|
+ <div class="des-state-item fl">
|
|
|
+ <img
|
|
|
+ src="~@/assets/img/svg/read.svg"
|
|
|
+ class="des-state-icon"
|
|
|
+ />
|
|
|
+ <span>{{ item.browse }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="des-state-item fl">
|
|
|
+ <img
|
|
|
+ src="~@/assets/img/svg/like.svg"
|
|
|
+ class="des-state-icon"
|
|
|
+ />
|
|
|
+ <span>{{ item.hit }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="des-state-item fr">
|
|
|
+ <img
|
|
|
+ src="~@/assets/img/svg/del.svg"
|
|
|
+ class="des-state-icon"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="des-state-item fr" @click="editItem(idx)">
|
|
|
+ <img
|
|
|
+ src="~@/assets/img/svg/edit.svg"
|
|
|
+ class="des-state-icon"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <work-form
|
|
|
+ v-else
|
|
|
+ :key="`works_edit_${idx}`"
|
|
|
+ :idx="idx"
|
|
|
+ :work="works[idx]"
|
|
|
+ :industries="industries"
|
|
|
+ :functions="functions"
|
|
|
+ :handleCancel="handleCancel"
|
|
|
+ :onSubmit="onSubmit"
|
|
|
+ :handleDelete="handleDelete"
|
|
|
+ ></work-form>
|
|
|
+ </template>
|
|
|
+ <div class="sign-new-project-add" @click="handleAdd">
|
|
|
+ <img
|
|
|
+ src="~@/assets/img/svg/add-project.svg"
|
|
|
+ class="sign-new-project-add-icon"
|
|
|
+ />
|
|
|
+ <div class="sign-new-project-add-tips">添加作品</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-else class="empty">
|
|
|
+ 点击右上角“添加”按钮添加作品(至少添加1项)
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="sign-new-next">
|
|
|
+ <div class="sign-new-next-btn">下一步</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapState } from "vuex";
|
|
|
+import qs from "qs";
|
|
|
+import workForm from "./work-form";
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ // editing: true,
|
|
|
+ editingItem: [],
|
|
|
+ init: {
|
|
|
+ name: "",
|
|
|
+ industry_id: "",
|
|
|
+ function_ops: "",
|
|
|
+ duty: "",
|
|
|
+ description: "",
|
|
|
+ url: "",
|
|
|
+ image_list: []
|
|
|
+ },
|
|
|
+ works: [],
|
|
|
+ current: null,
|
|
|
+ originWorks: [],
|
|
|
+ industries: [],
|
|
|
+ functions: []
|
|
|
+ };
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ workForm
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState(["userinfo"])
|
|
|
+ },
|
|
|
+ watch: {},
|
|
|
+ async mounted() {
|
|
|
+ await this.getIndustry();
|
|
|
+ this.getFunction();
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async onSubmit(work, idx) {
|
|
|
+ const queryParams = {
|
|
|
+ ...work,
|
|
|
+ // id: 1, //传ID是更新,不传ID是新增
|
|
|
+ // name: "作品名称",
|
|
|
+ // duty: "作品指责",
|
|
|
+ // description: "作品描述",
|
|
|
+ function_ops: work.function_ops.join(","), //是多个ID,用英文逗号分割,关键功能
|
|
|
+ industry_id: parseInt(work.industry_id[1]), //id,是int类型啊,不是文字
|
|
|
+ // url: "https://a.com",
|
|
|
+ image_list: work.image_list.map(it => it.url).join(",") //是图片地址,多个图片用逗号分割,
|
|
|
+ };
|
|
|
+ const res = await this.$axios.$post(`/api/user_works/save`, queryParams);
|
|
|
+ if (res.status === 1) {
|
|
|
+ this.$message.success("保存成功!");
|
|
|
+ this.init = {
|
|
|
+ name: "",
|
|
|
+ industry_id: "",
|
|
|
+ function_ops: "",
|
|
|
+ duty: "",
|
|
|
+ description: "",
|
|
|
+ url: "",
|
|
|
+ image_list: []
|
|
|
+ };
|
|
|
+ this.editingItem = [];
|
|
|
+ this.getData();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async getData() {
|
|
|
+ const res = await this.$axios.$post("/api/user_works/get_list");
|
|
|
+ const data = !res.data ? [] : res.data;
|
|
|
+ this.works = data.map(it => {
|
|
|
+ const image_list = it.image_list
|
|
|
+ ? it.image_list.split(",").map(it => ({ name: it, url: it }))
|
|
|
+ : [];
|
|
|
+ let industry_id;
|
|
|
+ this.industries.map(item1 => {
|
|
|
+ return item1.children.map(item2 => {
|
|
|
+ if (item2.value == it.industry_id) {
|
|
|
+ industry_id = [item1.value, item2.value];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ console.log(industry_id);
|
|
|
+ return {
|
|
|
+ ...it,
|
|
|
+ industry_id,
|
|
|
+ function_ops: it.function_ops ? it.function_ops.split(",") : [],
|
|
|
+ image_list
|
|
|
+ };
|
|
|
+ });
|
|
|
+ },
|
|
|
+ async getIndustry() {
|
|
|
+ const res = await this.$axios.$post("/api/user_works/get_industry");
|
|
|
+ const data = !res.data ? [] : res.data;
|
|
|
+ this.industries = data.map(it => ({
|
|
|
+ label: it.name,
|
|
|
+ value: it.id,
|
|
|
+ children: it.child.map(it => ({
|
|
|
+ label: it.name,
|
|
|
+ value: it.id
|
|
|
+ }))
|
|
|
+ }));
|
|
|
+ return this.industries;
|
|
|
+ },
|
|
|
+ async getFunction() {
|
|
|
+ const res = await this.$axios.$post("/api/user_works/get_function");
|
|
|
+ const data = !res.data ? [] : res.data;
|
|
|
+ this.functions = data.map(it => ({
|
|
|
+ label: it.outsourcefunc_name,
|
|
|
+ value: it.outsourcefunc_id
|
|
|
+ }));
|
|
|
+ },
|
|
|
+ async fetchWork(keyword) {
|
|
|
+ // console.log(keyword);
|
|
|
+ // this.loadingWork = true;
|
|
|
+ // const res = await this.$axios.$post("/api/simple_data/select_skill", {
|
|
|
+ // keyword
|
|
|
+ // });
|
|
|
+ // this.loadingWork = false;
|
|
|
+ // const data = res.data || [];
|
|
|
+ // this.skillList = data.map(it => ({ value: it.id, label: it.name }));
|
|
|
+ },
|
|
|
+ handleAdd() {
|
|
|
+ if (this.userinfo && this.userinfo.realname_verify_status === "0") {
|
|
|
+ this.$message.error("请先进行实名认证");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (this.editingItem.length > 0 && !this.works[this.editingItem[0]].id) {
|
|
|
+ this.$message.error("请先保存现有修改");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // this.works.push(this.init);
|
|
|
+ // this.editingItem = [this.works.length - 1];
|
|
|
+ window.location.href = "/otherpage/works/create";
|
|
|
+ },
|
|
|
+ async handleDelete(work, idx) {
|
|
|
+ const deleteComplete = () => {
|
|
|
+ this.$message({
|
|
|
+ type: "success",
|
|
|
+ message: "删除成功!"
|
|
|
+ });
|
|
|
+ this.works.splice(idx, 1);
|
|
|
+ this.editingItem = [];
|
|
|
+ };
|
|
|
+ this.$confirm("确认删除该作品?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ })
|
|
|
+ .then(async () => {
|
|
|
+ if (work.wid) {
|
|
|
+ const res = await this.$axios.$post(`/api/user_works/delete`, {
|
|
|
+ id: work.wid
|
|
|
+ });
|
|
|
+ if (res.status === 1) {
|
|
|
+ deleteComplete();
|
|
|
+ // this.$message.success(res.info);
|
|
|
+ this.getData();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ deleteComplete();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ console.log(err);
|
|
|
+ this.$message({
|
|
|
+ type: "info",
|
|
|
+ message: "已取消删除"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ handleCancel(work, idx) {
|
|
|
+ this.editingItem = [];
|
|
|
+ if (!work.wid) {
|
|
|
+ this.works.splice(idx, 1);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ editItem(idx) {
|
|
|
+ // this.editingItem = [idx];
|
|
|
+ window.location.href =
|
|
|
+ "/otherpage/works/create?wid=" + this.works[idx].wid;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.sign-project-main {
|
|
|
+ header .el-icon-plus {
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+ .show {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 30px 24px;
|
|
|
+ background: #ffffff;
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px solid #ced3d9;
|
|
|
+ margin-bottom: 30px;
|
|
|
+
|
|
|
+ &:last-of-type {
|
|
|
+ /* border: 0; */
|
|
|
+ margin-bottom: 30px;
|
|
|
+ }
|
|
|
+ .star {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 100px;
|
|
|
+ img {
|
|
|
+ margin-bottom: 5px;
|
|
|
+ width: 26px;
|
|
|
+ height: 26px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .image {
|
|
|
+ margin-right: 10px;
|
|
|
+ width: 116px;
|
|
|
+ height: 116px;
|
|
|
+ overflow: hidden;
|
|
|
+ background-position: 50% 50%;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: cover;
|
|
|
+ }
|
|
|
+ .des {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+ h4 {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ height: 24px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-family: PingFangSC-Medium;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #308eff;
|
|
|
+ line-height: 24px;
|
|
|
+ }
|
|
|
+ p {
|
|
|
+ font-size: 14px;
|
|
|
+ font-family: PingFangSC-Regular;
|
|
|
+ font-weight: 400;
|
|
|
+ color: rgba(102, 102, 102, 1);
|
|
|
+ line-height: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .empty {
|
|
|
+ margin: 112px auto 104px;
|
|
|
+ font-size: 27px;
|
|
|
+ font-family: PingFangSC-Regular;
|
|
|
+ font-weight: 400;
|
|
|
+ text-align: center;
|
|
|
+ color: rgba(205, 205, 205, 1);
|
|
|
+ line-height: 38px;
|
|
|
+ }
|
|
|
+ footer p {
|
|
|
+ margin-top: 15px;
|
|
|
+ width: 766px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-family: PingFangSC-Regular;
|
|
|
+ font-weight: 400;
|
|
|
+ color: rgba(145, 154, 167, 1);
|
|
|
+ line-height: 17px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.sign-project-main {
|
|
|
+ margin-top: 60px;
|
|
|
+ margin-bottom: 130px;
|
|
|
+ .sign-new-header {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.des-title {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.des-title-name {
|
|
|
+ font-size: 16px;
|
|
|
+ font-family: PingFangSC-Medium, PingFang SC;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #0b111a;
|
|
|
+ line-height: 21px;
|
|
|
+ max-width: 35em;
|
|
|
+}
|
|
|
+.des-title-time {
|
|
|
+ font-size: 13px;
|
|
|
+ font-family: PingFangSC-Regular, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #828c99;
|
|
|
+ line-height: 18px;
|
|
|
+}
|
|
|
+.des-content {
|
|
|
+ margin-top: 8px;
|
|
|
+ font-size: 13px;
|
|
|
+ font-family: PingFangSC-Regular, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #828c99;
|
|
|
+ line-height: 18px;
|
|
|
+}
|
|
|
+.des-state {
|
|
|
+ margin-top: 15px;
|
|
|
+ overflow: hidden;
|
|
|
+ .fl {
|
|
|
+ float: left;
|
|
|
+ margin-right: 20px;
|
|
|
+ .des-state-icon {
|
|
|
+ margin-right: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .fr {
|
|
|
+ float: right;
|
|
|
+ margin-left: 20px;
|
|
|
+ .des-state-icon {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.des-state-icon {
|
|
|
+ // width: 14px;
|
|
|
+ height: 16px;
|
|
|
+}
|
|
|
+.des-state-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ span {
|
|
|
+ font-size: 12px;
|
|
|
+ font-family: PingFangSC-Regular, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #828c99;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.text-line-3 {
|
|
|
+ display: -webkit-box;
|
|
|
+ word-break: break-all;
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+ -webkit-line-clamp: 3;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+}
|
|
|
+.sign-new-project-add {
|
|
|
+ height: 176px;
|
|
|
+ background: #ffffff;
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px solid #ced3d9;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.sign-new-project-add-icon {
|
|
|
+ width: 36px;
|
|
|
+}
|
|
|
+.sign-new-project-add-tips {
|
|
|
+ margin-top: 16px;
|
|
|
+ font-size: 16px;
|
|
|
+ font-family: PingFangSC-Regular, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #0b121a;
|
|
|
+ line-height: 22px;
|
|
|
+}
|
|
|
+.sign-new-works-list {
|
|
|
+ margin-top: 18px;
|
|
|
+}
|
|
|
+.sign-new-project {
|
|
|
+ padding-bottom: 30px;
|
|
|
+}
|
|
|
+</style>
|